spring源碼分析——依賴注入(set注入、構造器注入、Autowired注解注入)


 

  spring容器的核心IOC和Aop,其中ioc控制反轉,就是spring容器幫助程序員創建對象以及維護對象之間的依賴關系,

DI依賴注入就是其中非常重要的一環,我們平常使用比較多的就是set注入、構造器注入,使用@Autowired、@Resource注解注入等,

下面我們就分析一下spring源碼是怎么實現的。

一:set注入

准備環境:

在spring-context.xml中配置student的bean信息

	<bean id="student" class="com.hello.model.Student">
		<property name="height" value="100"></property>
		<property name="weight" value="300"></property>
	</bean>

  

 

 

運行結果:

 

 

 

 下面從源碼來看一下set注入:

在解析spring-context.xml的時候,解析bean元素,會解析到子元素property,這個部分在默認標簽解析那節分析過,然后把屬性值封裝

到MultablePropertyValues對象上,放到BeanDefinition對象上面緩存

 

 

 

進入polulateBean方法中:

從BeanDefinition對象中拿到PropertyValues屬性:

 

 

應用屬性值:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 剛才我們使用的是set注入,直接注入的字符串,如果使用ref,注入對象,會如何處理?

看一下下面標注的這行代碼,根據原始值獲取value值:

 

 

如果是字符串類型,則直接獲取字符串的值,上面的value=“100”,就是走到這里

 

 

如果是引用類型,會走到如下分支代碼:

 

 

根據參數名稱,到beanFactory容器中獲取bean對象,其他的步驟和字符串的value一樣

 

 二:構造器注入

構造器注入的方式就是上一節分析的有參數構造器的創建過程,在實例化的過程中就實現了注入

	<bean id="student" class="com.hello.model.Student">
		<constructor-arg index="0" value="100"/>
		<constructor-arg index="1" value="200"/>
	</bean>

運行結果:

 

 分析過程見上一節實例化對象的分析

三:@Autowired注解注入依賴

准備工作:

 

 運行結果:

 

這里面有兩個比較重要的對象AutowireAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor

首先要埋點,創建BeanDefinition對象,然后注冊到BeanDefinitionMaps緩存中,看一下ComponentScanBeanDefinitionParser類

 

 

注冊注解輔助相關組件:

 

 

將AutowiredAnnotationBeanPostProcessor封裝成BeanDefinition對象,注冊到BeanDefinitionMaps緩存中

 

 

注冊完成后,就要實例化對象,實例化的動作實在refresh方法的registerBeanPostProcessors方法中完成的,這一步在之前分析BeanPostProcessor接口的時候已經分析過

 

這一步完成后,AutowiredAnnotationBeanPostProcessor對象就被注冊到了BeanPostProcessors集合中,以備后面攔截使用

 

 

 

注冊beanDefinition完成,實例化對象完成,下面就要看具體的攔截使用。

 

 我們來看一下搜集過程:

 

 

 

 搜集類上的注解信息:

 

搜集字段和方法上的注解信息:

 

 

 

 

 因為我們的@Autowired注解是在屬性上,所以我們看一下解析字段屬性的代碼塊

 

 

 

 

搜集到Cat cat 屬性上面有Autowired注解信息

 

 到這里類clazz的注解屬性信息搜集完畢,放入緩存中

回到populateBean方法中,設置bean對象的屬性

 

 

 

 從緩存中取出注解元數據信息:

 

 

注入依賴對象:

 

 

 

 

到容器singletonObjects緩存中查找或者實例化對象,然后反射實現對象注入

 

 

 

尋找依賴:

 

 

 

 

 

 

 

 

 

 實例化依賴的bean對象,然后在上一步反射實現注入,到這里Autowired注解實現依賴注入的過程就結束了。

 

總結:依賴注入是spring容器IOC能夠實現的核心功能,spring容器幫助我們維護對象之間的關系。

set注入:主要是在解析的時候property屬性封裝到BeanDefinition對象上,然后在pupulateBean設置屬性的時候,

從BeanDefinition的MultiPropertyValues中取出數據,然后通過反射設置到對象上,如果設置的值為bean,那么在解析的時候

會用到一個runtimeRefence,然后在populateBean的時候再通過getBean實例化對象

構造器注入,在創建對象的時候,從BeanDefinition的ConstructArgs中取出數據,反射尋找有參數構造器,然后創建對象實例

@Autowired注解主要實現依賴於AutowiredAnnotationBeanPostProcesor,埋點,注冊BeanDefinition,實例化,搜集注解信息,攔截根據屬性getBean尋找bean對象,反射注入。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM