IOC和DI說明 IOC(Inversion of Control)控制反轉(zhuǎn):所謂控制反轉(zhuǎn),就是把原先我們代碼里面需要實現(xiàn)的對象創(chuàng) 建、依賴的代碼,反轉(zhuǎn)給容器來幫忙實現(xiàn)。那么必然的我們需要創(chuàng)建一個容器,同時需要一種描述來讓 容器知道需要創(chuàng)建的對象與對象的關(guān)系。這個描述最具體表現(xiàn)就是我們可配置的文件。 DI(Dependency Injection)依賴注入:就是指對象是被動接受依賴類而不是自己主動去找,換句話說 就是指對象不是從容器中查找它依賴的類,而是在容器實例化對象的時候主動將它依賴的類注入給它。 可能有很多官方的解釋,但我所理解的IOC容器,其實就可以理解成spring維護的一個Map<String,Object>。各個對象之間的關(guān)系以及所有的bean的信息,都由spring Ioc容器來儲存,實例的生命周期由IOC容器控制。當然,若想要spring幫你管理,那你就必須按照spring的規(guī)則來,其中比較常用的兩種方式是xml和注解方式。 Spring 架構(gòu)圖 本文主要講述的是最下邊的Core container模塊,也是spring的核心模塊 Spring 核心容器體系結(jié)構(gòu)
DefaultListableBeanFactory中有一個成員變量 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);在注冊階段變化給其賦值,將xml或者其他的配置轉(zhuǎn)換為spring能理解的數(shù)據(jù)結(jié)構(gòu)從而可以在getbean階段可以得到實例。
主線說明 Spring在IOC和DI的過程主要分為兩步: 1. IOC容器初始化 2. 依賴注入getbean IOC初始化步驟
注冊
<bean id='helloWorld' class='org.czx.spring.ioc.HelloWorld'> <property name='name' value='Spring'></property></bean> 使用xml的ClassPathXmlApplicationContext的refresh()方法,初始化,加載資源 xml解析,轉(zhuǎn)換為docment對象,然后解析docment對象,對于不同element節(jié)點進行做不同的處理,最后轉(zhuǎn)換成BeanDefinition的定義格式,根據(jù)id等其他唯一標識,將bean的定義存入緩存中,完成IOC容器的初始化。這個是主線,對于校驗,多種格式的解析,是否單例處理,這些就需要看具體處理邏輯了。至此就完成了初始化階段,所以可以看出來初始化階段容器并不會去生成對象,除非bean配置lazy-init=ture; 依賴注入getbean 當我們調(diào)用getbean方法時候就會觸發(fā)依賴注入了,將屬性值或者屬性對象都會根據(jù)配置去生成,spring生成的對象怎樣一切依賴的配置,spring并不干涉。 依賴注入流程: 依賴注入過程就是生成一個對象,將屬性和配置的value值進行對應(yīng),然后使用工廠去生成,在這里大量使用策略模式,對于不同對象需要不同的模型去產(chǎn)生。還有一個金典的地方需要注意的是產(chǎn)生的并不是一個我們定義的對象,spring巧妙的運用了裝飾器模式定義一個BeanWrapper,最后產(chǎn)生的bean都是beanWrapper,這個beanwrapper是bean的一個增強,在docreatebean時候,可以通過反射去生成一個beanWrapper也可以通過動態(tài)代理去實現(xiàn)beanWrapper,這也就是為之后spring實現(xiàn)AOP的功能做了鋪墊。 結(jié)語 對于Spring ioc的很多細節(jié)沒有說明,源碼需要自己去看才知道細節(jié)的實現(xiàn),對于spring的ioc和di的具體實現(xiàn),可以看看github上簡要的實現(xiàn): |
|