注:本文中所有的“@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注入的先后順序的結果大家都是知道的,本次只是通過應用的層面來側面證明一下,以后有機會可以從源碼角度和大家分享一下它們注入的先后順序