控制反轉IOC(Inversion of Control),是一種設計思想,DI(依賴注入)是實現IoC的一種方法,也有人認爲DI只是IoC的另外一種說法。沒有IoC的程序中咱們使用面向對象編程對象的建立與對象間的依賴關係徹底硬編碼在程序中,對象的建立由程序本身控制,控制反轉後將對象的建立轉移給第三方(容器),所謂的控制反轉就是:得到依賴對象的方式反轉了。spring
IOC的思想核心的地方在於,資源不禁使用資源的雙方管理,而由不使用資源的第三方管理,這能夠帶來不少好處。第一,資源集中管理,實現資源的可配置和易管理。第二,下降了使用資源雙方的依賴程度,也就是咱們說的耦合度。編程
Spring IOC設計中,主要有兩個容器系列(下圖):一是實現BeanFactory接口的簡單容器,僅實現了最基本的功能;二是ApplicationContext應用上下文,做爲容器的高級形態,增長了面向框架的特性。數據結構
Spring經過定義BeanDefinition來管理基於Spring的應用中的各類對象以及它們之間的依賴關係。IOC容器是用來管理對象依賴關係的,對於IOC容器來講,BeanDefinition就是對依賴反轉模式中管理對象關係的數據抽象(核心數據結構)。BeanDefinition就像容器裝的水,有了基本數據,容器才能發揮做用。框架
BeanFactory接口定義了IOC容器最基本的形式,提供使用IOC容器所須要遵照的最底層和最基本的編程規範。編碼
BeanFactory是個Factory,也就是IOC容器或對象工廠。最主要的方法就是getBean(String beanName),該方法從容器中返回特定名稱的Bean,只不過其中有一種Bean是FacotryBean。spa
FactoryBean 是一種特殊的bean,實際上也是一個工廠,經過FactoryBeanName獲得FacotryBean建立的Bean,它經過getObject()建立的Bean。要想獲得FactoryBean自己,必須經過&FactoryBeanName獲得,即在BeanFactory中經過getBean(&FactoryBeanName)來獲得 FactoryBean。設計
注:在spring 中是經過BeanFactoryUtils.isFactoryDereference()來判斷一個Bean是不是FactoryBean.對象
spring 內部實現中應該是在經過BeanFacotry 的getBean(String beanName) 來獲得Bean時,若是這個Bean是一個FactoryBean,則把它生成的Bean返回,否者直接返回Bean。繼承
這裏以XMLBeanFactory爲例,初始化過程:遞歸
1.建立IOC配置文件的抽象資源,包括BeanDefinition的定義信息。
2.建立一個BeanFactory,這裏使用DefaultListableBeanFactory。
3.建立一個載入BeanDefinition的讀取器,這裏使用XMLBeanDefinitionReader來載入XML文件形式的BeanDefinition,經過一個回調配置給BeanFactory。
4.從定義好的資源位置載入配置信息,具體的解析過程由XMLBeanDefinitionReader來完成。完成整個載入和註冊Bean定義以後,須要的IOC容器就簡歷起來了。這個時候就可使用IOC容器了。
ApplicationContext是一個高級形態意義的IOC容器,提供瞭如下特性:
1.支持不一樣的信息源。擴展MessageResource接口,例如支持國際化實現。
2.訪問資源。對ResourceLoader和Resource支持,可從不一樣的地方獲取Bean定義資源。
3.支持應用事件。繼承了接口ApplicationEventPublisher,在上下文引入事件機制。
4.在ApplicationContext中提供附加服務。使其具備面向框架的使用風格。
完成BeanDefinition註冊後,就完成了IOC容器的初始化過程,此時已經創建了整個Bean的配置信息,BeanDefinition已經能夠被使用了,都在beanDefinitionMap裏被檢索和使用。容器的做用就是對這些信息進行處理和維護。
依賴注入的過程是用戶第一次向IOC容器索要Bean(getBean)時觸發,也可在BeanDefinition經過控制lazy-init屬性來讓容器完成對Bean的預實例化。
在Bean的建立和對象依賴注入的過程當中,須要根據BeanDefinition中的信息來遞歸的完成依賴注入。遞歸都是以getBean爲入口。一個遞歸是在上下文中查找須要的Bean和建立Bean的遞歸調用;另外一個遞歸是在依賴注入時,經過遞歸調用容器訂單getBean方法,獲得當前Bean的依賴Bean,同時出發對依賴Bean的建立和注入。
在Bean建立和對象依賴注入完成之後,在IOC容器中創建起一系列依靠依賴關係聯繫起來的Bean, 經過IOC容器的相關接口方法,就能夠很是方便的供上層應用使用了。