为什么 Spring 构造器注入不需要 @Autowired 注解


Spring 三种注入方式

实习的时候看公司的项目代码,发现一个有意思的事情,Service、Controller里面注入属性时不是直接使用 @Autowired 进行注入的,而是选择了直接使用构造器的方式,因此来总结一下Spring 常用的注入方式

属性注入

其实这是我在学习 SpringBoot 时最常用的方式,直接在需要注入的属性上添加 @Autowired 注解,简单明了。

@RestController
public class TestController {
    @Autowired
    private TestService testService;
    @RequestMapping("/test")
    public String test() {
        return testService.test();
    }
}

使用 Autowired 注解,Spring 默认会在容器中找到对应类型的实例进行注入,当然,你也可以设置成根据属性名来进行注入。

这种方式是最简单的,但同时也是最不被推荐的。

setter 注入

简而言之,就是利用对象的 setter 方法来进行注入

@Controller
public class TestController {
  private TestService testService;
   
  @Autowired
  public void setTestService(TestService testService) {
      this.testService = testService;
  }
}

这种方式在 Spring3.x 的时候是非常推荐的,不过我倒是没咋见过它的使用。

构造器注入

这就是目前 Spring 最为推荐的注入方式,直接通过带参构造方法来注入,我也是看公司项目代码时才发现的,虽然学 Spring 的时候有提过,不过自己也一直没用过,忘完了!

@Controller
public class TestController{
    private final TestService testService;
    public TestController(TestService testService){
        this.testService = testService;
    }
}

甚至于,在我们需要注入的对象非常多的时候,我们借助 Lombok 连构造方法都不用写了

@RestController("xxx")
@RequestMapping("/x")
@AllArgsConstructor
public class AccountRelSiteController extends BaseController {
    private final XxxService xxxService;
    private final YyyService yyyService;
    private final ZzzService zzzService;
}

发现没有,这里并没有用到 @Autowired 这样的注解,甚至没出现任何能代表注入字样的标记,而我们却能正常的使用注入的对象,这是为什么?我不知道,所以赶紧去 StackOverFlow 看看有没有和我一样疑惑的老哥!

image-20211201201032673

还真有人和我一样疑惑,不过他的猜测是 @AllArgsConstructor 注解注入了对象,当然这是不对的,因为我们不使用 Lombok 也能注入成功,在其它人的回答中我看见了 Spring 的官方文档中的一段,其中给出了解释:

As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean only defines one constructor to begin with. However, if several constructors are available, at least one must be annotated to teach the container which one to use.

也就是说,这是 Spring 框架自身的一个特性,对于一个 SpringBean 来说,如果其只有一个构造方法,那么 Spring 会使用该构造方法并自动注入其所需要的全部依赖

详情可见 Spring 4.3 的文档中对 @Autowired 注解的解释,beans-autowired-annotation


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM