(一)Spring IOC容器的設計與實現

控制反轉

Spring IoCIoC全稱是"Inversion of Control",譯:控制反轉數據結構

"控制反轉"又稱"依賴反轉"編碼

DI全稱是"Dependency Injection",譯:依賴注入設計

使用控制反轉,依賴注入後,當建立對象時,由一個調度系統將其所依賴的對象的引用傳遞給它(這些對象也都來自於調度系統所管理的對象),即依賴被注入到對象中。因此,控制反轉是關於一個對象如何獲取它所依賴的對象的引用code

上述的調度系統是應用平臺,具體來講是IoC容器。經過使用IoC容器,對象依賴關係的管理被反轉了,轉到IoC容器中來了,對象之間的相互依賴關係由IoC容器進行管理,並由IoC容器完成對象的注入xml

IoC容器的核心數據結構

BeanDefinitionIoC容器的核心數據結構。又稱"Bean定義信息"。是建立Bean實例時所使用的模板對象

Bean是容器管理的對象的統稱blog

容器在建立Bean實例以前會先建立BeanDefinition對象,它保存了Bean的定義信息,例如Bean的名字,類型,是單實例仍是多實例,是否是懶加載,所依賴的其餘對象有哪些等接口

IoC容器的設計與實現

IoC容器有兩個系列生命週期

一個是實現BeanFactory接口的簡單容器系列,這個系列的容器能實現容器的最基本的功能。又稱"Bean工廠"事件

一個是實現ApplicationContext接口的高級容器系列,它是容器的高級形態。又稱"應用上下文"或"上下文"。上下文在簡單容器的基礎上又增長了許多新功能

Spring IoC容器的設計

下面這張圖描述的IoC容器的接口設計圖,IoC容器的實現類就是以容器的接口設計爲基礎實現的

設計主線

  • BeanFactory爲核心。從BeanFactoryHierarchicalBeanFactory再到ConfigurableBeanFactory。這是一條主要的BeanFactory類型容器的設計路線
  • ApplicationContext爲核心。從BeanFactoryListableBeanFactoryApplicationContext,再到ConfigurableApplicationContextWebApplicationContext。咱們經常使用的上下文基本都是ConfigurableApplicationContextWebApplicationContext的實現類

咱們經常使用的BeanFactory的實現類是DefaultListableBeanFactory。同時,以這個實現類爲基礎,又有許多應用於不一樣場景下的子類bean工廠。不過咱們一般直接使用DefaultListableBeanFactory

咱們經常使用的ApplicationContext的實現類是AbstractApplicationContext的子類。這個抽象類包含了容器的初始化方法refresh()

AbstractApplicationContext實現的是ConfigurableApplicationContext接口。

BeanFactory的設計原理

這些接口方法定義出了一個基本的IoC容器

  • boolean containsBean(String name);容器中是否有名爲nameBean
  • String[] getAliases(String name);查詢Bean的全部別名
  • getBean()有多個重載方法,是從容器中獲取Bean實例的方法(此方法包含若是獲取不到就建立一個Bean實例的流程)
  • boolean isSingleton(String name);返回Bean是不是單實例
  • boolean isPrototype(String name)返回Bean是不是多實例(Bean是單實例仍是多實例,這些信息保存在對應的BeanDefinition對象中)
  • ...

這些方法提供了容器最基本的功能

ApplicationContext的設計原理

ApplicationContext除了實現了BeanFactory外還實現了其餘接口,爲容器添加了其餘功能

  • MessageSource信息源。支持國際化功能的實現
  • ResourceLoader訪問資源。用於獲取 Bean的定義信息所在的資源,爲建立 BeanDefinition對象作準備
  • ApplicationEventPublisher發佈事件。能夠在上下文中,在Bean的生命週期中發佈事件
  • ...

容器初始化流程

首先,由編碼者使用某種形式編寫Bean的配置信息,例如在.xml文件中寫<bean>標籤配置Bean

而後,啓動容器進行初始化。容器初始化大體分三步

  1. BeanDefinitionResource定位(定位Bean配置信息所在位置)
  2. 載入BeanDefinition(建立BeanDefinition對象)
  3. 向容器註冊BeanDefinition對象(在容器內部將對象put到一個容器持有的map對象中)

在第一次調用容器的getBean()方法(BeanFactory中定義的方法)獲取Bean對象時,若是對象還未被實例化,就獲取對應的BeanDefinition對象,並使用它做爲模板建立實例對象

再容器完成初始化後,調用refresh()方法刷新容器。方法執行完後容器即可以使用

ps:容器初始化的流程可能在refresh()方法外執行,也可能在refresh()方法內執行

相關文章
相關標籤/搜索