Spring-@Autowired、@Resource、@Inject区别以及Spring为什么建议建议用构造器的方式注入
@Autowired
Spring提供的注解
@Autowired
private Test test;
装配顺序:
- 按照type在上下文中找bea,即查找类型为Test的bean
- 如果有多个bean,那么按照name进行匹配:
2.1 如果有@Qualifier注解,那么按照@Qualifier指定的name进行匹配
2.2 如果没有@Qualifier注解,则根据变量名进行匹配,查找name为test的bean - 匹配不到则报错,如果定义了@Autowired(required=false)(默认为true),注入失败也不会抛出异常
@Inject
在Spring环境下,@Inject和@Autowired是相同的,因为都是使用AutowiredAnnotationBeanPostProcessor来处理的。
@Inject是JSR-330定义的规范
@Resource
@Resource是JSR-250定义的规范
Spring 在 CommonAnnotationBeanPostProcessor实现了对JSR-250的注解的处理,其中就包括@Resource
@Resource有两个重要的属性:name和type,Spring分别对应解析成bean的name和type
装配顺序:
- 如果同时指定name和type,那么从Spring的上下文中精确匹配,找不到则抛出异常
- 如果指定了name,则匹配name,找不到则抛出异常
- 如果指定type,则匹配type,找不到或找到多个都会抛出异常
- 如果既没有指定name,也没有指定type,那么会先匹配name,再匹配type
Spring的注入方式
Spring有三种注入方式
基于Field注入
在属性上通过注解进行注入,本质上是通过反射的方式直接注入到field,平常使用最多的一种方式,但是不推荐。
@Autowired
private Test test;
基于setter方法注入
通过对应变量的setter方法以及在方法上使用注解
private Test test;
@Autowired
public void setTest(Test test){
this.test = test;
}
注:在 Spring 4.3 及以后的版本中,setter 上面的 @Autowired 注解是可以不写的。
基于constructor注入
将各个必须的依赖全部方式构造函数中
private Test test;
@Autowired
public Service(@Qualifier("test")Test test){
this.test = test;
}
在 Spring 4.3 及以后的版本中,如果这个类只有一个构造方法,那么这个构造方法上面也可以不写 @Autowired 注解。
基于field注入的坏处
- 违背单一职责,就算一个类中有N多个依赖都不会发现
- 依赖注入与容器本身耦合,当前类不能通过反射进行实例化,必须通过依赖容器进行实例化
- 不能注入final变量修饰的对象
Spring推荐使用构造器注入
-
基于setter的注入,只应该被注入非必需的依赖,如果使用setter注入的话,代码中可能会有过多的null检查。
-
构造方法完成依赖注入的组件 ,在被调用时可以保证它们都完全准备好了。
-
防止代码承担过多职责
https://mp.weixin.qq.com/s/PGH9EoQsemc69ikb3eyllw