写在前面
相信很多同学一直用的是@Autowired
, 另外也都知道都能用,但是也不知道有啥子区别。看看下面的以后就不怕别人问你为什么用她而不用他了。
结论
先说结论: 推荐用构造器方式,简单粗暴的原因是人家Spring在Spring4.x版本中推荐的写法。
区别
@Autowired
这位兄弟是根据type装配哒。默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。而它是spring的产物.
@Resource
而这位老兄呢,是jdk的产物。是按name来装配的,但也可以通过type来装配。
@Resource装配顺序
- 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
- 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
- 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
- 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
构造器
举个例子吧!
public class A {
private final Field field;
public A(Field field) {
this.field = field;
}
}
但我通常写都用结合lombok
食用,更香点。不知道的同学查查是什么哟!
@AllArgsConstructor //看名字就知道什么意思,同上面例子一模一样,写法简洁一点
public class A {
private final Field field;
}
Spring 这么说了
google翻译
Spring团队通常提倡构造函数注入,因为它使人们能够将应用程序组件实现为不可变的对象并确保所需的依赖项不为null。此外,注入构造函数的组件总是以完全初始化的状态返回到客户端(调用)代码。
画重点
- 不可变对象:所以为什么依赖对象前面要加个final
- 确保依赖对象不为null: 不致于在正调用时才报错,直接启动就报错。
对比
对于IOC容器以外的环境,除了使用反射来提供它需要的依赖之外,无法复用该实现类。而且将一直是个潜在的隐患,因为你不调用将一直无法发现NPE的存在。
另外,使用field注入可能会导致循环依赖
。
如果使用构造器注入,在spring项目启动的时候,就以此告诉你的程序循环依赖。
会报The dependencies of some of the beans in the application context form a cycle
如果是field注入的话,启动的时候不会报错,在使用那个bean的时候才会报错。