注:本文中所有的“@Autowired和@Resource注入的先手顺序”一词都是指两个注解类是先通过Type注入还是先通过Name注入,并非是指两个注解在spring中执行的先后顺序
最近听子路老师讲课,课上讲解关于@Autowired和@Resource是先通过type还是先通过name注入属性的知识有点心得。
子路老师从源码的角度给大家讲了两个注解的先后顺序,但是如何通过应用的层面来进行验证呢?经过一番思考,想到了一种情况可以证明,分享给大家
1、创建一个FeiyangConfig配置类,添加扫描注解
@Configuration @ComponentScan("com.feiyang") public class FeiyangConfig { }
2、创建一个Zilu类和Feiyang类并交给spring容器管理
@Component public class Zilu { }
@Component public class Feiyang { }
3、创建一个Luban类,为该类添加Zilu feiyang和Feiyang zilu属性并添加@Autowired注解,提供一个打印两个属性的方法@Component
@Component public class Luban { @Autowired private Feiyang zilu; @Autowired private Zilu feiyang; public void print() { System.out.println("Feiyang zilu = " + zilu); System.out.println("Zilu feiyang = " + feiyang); } }
4、新建一个测试类,初始化spring容器,获取Luban bean,调用打印方法
public class Test { public static void main(String[] args) { ApplicationContext ac = new AnnotationConfigApplicationContext(FeiyangConfig.class); ac.getBean(Luban.class).print(); } }
5、运行代码,可以看到控制台打印信息
Feiyang zilu = com.feiyang.model.Feiyang@69a10787
Zilu feiyang = com.feiyang.model.Zilu@2d127a61
得出结论:@Autowired是先通过Type注入,后通过Name注入的。因为如果是先通过Name注入,那么Feiyang zilu注入的就应该是Zilu bean,而Zilu bean注入给Feiyang类型的属性必定会报错,所以不可能是先通过Name注入,只能是先通过Type注入的。
6、将两个属性的@Autowired注解修改为@Resource注解
@Component public class Luban { @Resource private Feiyang zilu; @Resource private Zilu feiyang; public void print() { System.out.println("Feiyang zilu = " + zilu); System.out.println("Zilu feiyang = " + feiyang); } }
由于@Resource是先通过Name注入的,所以初始化spring的时候一定会报错。为了验证结果,我们重复一遍4的步骤,控制台打印信息如下
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'luban': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'zilu' is expected to be of type 'com.feiyang.model.Feiyang' but was actually of type 'com.feiyang.model.Zilu'
Error creating bean with name 'luban': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'zilu' is expected to be of type 'com.feiyang.model.Feiyang' but was actually of type 'com.feiyang.model.Zilu'
这个报错信息的意思是创建Luban这个bean的时候失败,失败原因是注入名称为zilu的bean的时候应该是注入一个Feiyang类型的bean,但是获取到的却是Zilu类型的bean,这就说明@Resource是先通过Name注入的
总结:@Autowired和@Resource注入的先后顺序的结果大家都是知道的,本次只是通过应用的层面来侧面证明一下,以后有机会可以从源码角度和大家分享一下它们注入的先后顺序