關於@Autowired這個註解,咱們再熟悉不過了,常常跟@Resource來作對比,這篇文章咱們不討論二者有何異同,僅分析@Autowired的原理(基於Spring5)。java
假如一個接口(IUserService)有兩個實現類,分別是(UserServiceImpl01)和(UserServiceImpl02),在咱們給類注入的時候,這樣寫(@Autowired private IUserService userService)會發生什麼狀況?答案確定是報錯,那麼原理呢?文字描述:由於首先@Autowired是按照類型注入的,也就是.class,但UserServiceImpl01和UserServiceImpl02都是IUserService類型的,因而Spring就會按照後面的名字(userService)在容器中查找,但發現根本沒有這個名字,由於兩個實現類在不指定名字狀況下,就是首字母小寫的類名,而後拋出異常:expected single matching bean but found 2。。。app
還有不少種方法,但基本思想都同樣,無非就是如何區分兩個同祖宗的兒子,既然根兒相同,那就只有指定名字了。源碼分析
提到@Autowired咱們通常都知道叫依賴注入post
依賴注入:Dependency Injection,簡稱DI,說白了就是利用反射機制爲類的屬性賦值的操做。this
注入就是爲某個對象的外部資源賦值,注入某個對象所須要的外部資源(包括對象、資源、常量數據等)。IOC容器注入應用程序某個對象,應用程序所依賴的對象。spa
在完成對象的建立,爲對象變量進行賦值的時候進行注入(populate)。debug
可見它間接實現InstantiationAwareBeanPostProcessor,就具有了實例化先後(而不是初始化先後)管理對象的能力,實現了BeanPostProcessor,具備初始化先後管理對象的能力,實現BeanFactoryAware,具有隨時拿到BeanFactory的能力,也就是說,這個AutowiredAnnotationBeanPostProcessor具有一切後置處理器的能力。對象
首先找到須要注入的哪些元數據,而後metadata.inject(注入),注入方法點進去,來到InjectionMetadata的inject方法,在一個for循環裏面依次執行element.inject(target, beanName, pvs),來對屬性進行注入。blog
第584行,value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter),由工廠解析這個依賴,進入,來到DefaultListableBeanFactory第1065行,result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter)再次解析依賴,點擊進入,來到DefaultListableBeanFactory的doResolveDependency()方法,前面是一堆判斷,比較,查看屬性類型,這種類型的有幾個(matchingBeans),若是隻有一個匹配,那麼來到第1138行,instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this),進入這個方法,能夠看到就是前面說的根據工廠來建立實例的過程了:beanFactory.getBean(beanName),其中這個beanName就是屬性的名稱,當通過一系列操做完成屬性的實例化後,便來到AutowiredAnnotationBeanPostProcessor的第611行,利用反射爲此對象賦值。這樣,對象的建立以及賦值就完成了。繼承
在容器啓動,爲對象賦值的時候,遇到@Autowired註解,會用後置處理器機制,來建立屬性的實例,而後再利用反射機制,將實例化好的屬性,賦值給對象上,這就是Autowired的原理。