spring ioc之概念及結構分析(一)

ioc概念

許多非凡的應用都是經過兩個或者多個類經過彼此的合做來實現業務邏輯的,spring使用ioc(Inversion of Control​,控制反轉)來對這些對象來進行管理,起到經過第三方來管理對象的目的。java

爲何叫控制反轉?spring

誰控制誰,控制什麼:傳統Java SE程序設計,咱們直接在對象內部經過new進行建立對象,是程序主動去建立依賴對象;而IoC是有專門一個容器來建立這些對象,即由Ioc容器來控制對 象的建立;誰控制誰?固然是IoC 容器控制了對象;控制什麼?那就是主要控制了外部資源獲取(不僅是對象包括好比文件等)。爲什麼是反轉,哪些方面反轉了:有反轉就有正轉,傳統應用程序是由咱們本身在對象中主動控制去直接獲取依賴對象,也就是正轉;而反轉則是由容器來幫忙建立及注入依賴對象;爲什麼是反轉?由於由容器幫咱們查找及注入依賴對象,對象只是被動的接受依賴對象,因此是反轉;哪些方面反轉了?依賴對象的獲取被反轉了。後端

di概念

spring將大部分的對象都交給了ioc容器來管理,那麼咱們的應用是怎樣取得對象的實例的呢?這裏就使用了di(Dependency Injection,依賴注入)的概念,一個對象依賴於另一個對象,一些簡單的配置就可讓ioc容器將他所須要的對象實例注入。spring-mvc

爲何叫依賴注入?併發

  1. 誰依賴於誰:固然是應用程序依賴於IoC容器;mvc

  2. 爲何須要依賴:應用程序須要IoC容器來提供對象須要的外部資源;框架

  3. 誰注入誰:很明顯是IoC容器注入應用程序某個對象,應用程序依賴的對象;工具

  4. 注入了什麼:就是注入某個對象所須要的外部資源(包括對象、資源、常量數據)。.net

ioc和di是兩個不一樣的概念設計

ioc是將建立和管理對象交給了統一的一個容器去作,di是在你的對象中所依賴的其餘對象在ioc容器中去尋找,以便於建立和使用該對象。換句話說di是屬於ioc這個大功能的一小部分。

spring中的ioc的容器設計結構

咱們先來看看spring的ioc容器的接口設計圖

下面給出該容器設計結構的分析

  1. BeanFactory是全部容器的父級,BeanFactory實現了容器所具備的基本功能,如:getBean方法,獲取容器中註冊的bean
  2. 從接口設計圖能夠看出,從BeanFactory出發,分爲兩條線路,第一條是BeanFactory-HierarchcalBeanFactory-ConfigurableBeanFactory從源碼中咱們能夠看到HierarchcalBeanFactory較之BeanFactory多了兩個方法getParentBeanFactory能夠查看雙親的BeanFactory,還有個就是containsLocalBean該工廠是否包含一個bean。ConfigurableBeanFactory主要是對BeanFactory多了一些配置信息,如setParentBeanFactory設置雙親,setBeanClassLoader設置加載beanFactory的類加載器等。
  3. 第二條設計主線是以ApplicationContext應用上下文接口爲核心,路線是從BeanFactory-ListabelBeanFactory或者HierarchcalBeanFactory-ApplicationContext再到咱們經常使用的WebApplicationContext或者ConfigurableApplicationContext接口,這裏能夠看出ApplicationContext是個大容器也就是高級容器。

上面只是容器的接口設計圖,他的下面還有許多的實現類,也就是具體的ioc容器,下面咱們以xmlBeanFactory和XmlWebApplicationContext的實現爲例來講明ioc簡單的設計原理。

XmlBeanFactory結構介紹

輸入圖片說明

能夠看到XmlBeanFactory的根是BeanFactory,他的上一級是DefaultListableBeanFactory,這個類很重要,是咱們常常要用到的一個ioc的實現,好比ApplicationContext時就會用到他,DefaultListableBeanFactory實際上包含了基本ioc容器所具備的重要功能,所以在spring中將DefaultLitableBeanFactory做爲一個默認功能完整的ioc容器來使用。

從名字能夠看出XmlBeanFactory這是一個和xml相關的BeanFactory,那麼它是如何讀取解析xml呢?從源碼中能夠看出是經過XmlBeanDefinitionReader來解析的,其實XmlBeanFactory就是以DefaultLitableBeanFactory爲基類,再以XmlBeanDefinitionReader來解析xml格式的一個ioc容器,其餘不少相似的ioc容器都是經過持有或者擴展DefaultLitableBeanFactory來得到基本的ioc容器功能,如:ApplicationContext的子類AbstractRefreshableApplicationContext就持有DefaultLitableBeanFactory。

從spring 3.1版本後,經過代碼咱們能夠看到XmlBeanFactory是Deprecated(不推薦使用的)註釋爲@deprecated as of Spring 3.1 in favor of {@link DefaultListableBeanFactory} and{@link XmlBeanDefinitionReader}意思是推薦咱們使用這兩個的結合,而不是直接使用XmlBeanFactory,能夠這樣使用

Resource resource=new ClassPathResource("spring-mvc.xml");
        BeanDefinitionRegistry factory=new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions(resource);

其實就是將XmlBeanFactory的構造和初始化給拉出來了而已。

XmlWebApplicationContext的結構介紹

輸入圖片說明其中XmlWebApplicationContext是ApplicationContext中的實現接口 Application除了可以提供前面XmlBeanFactory提供的基本的ioc容器功能,還提供瞭如下附加功能

  1. 這裏是列表文本繼承MessageSource接口,使得ApplicationContext支持不一樣的信息源,這些信息源的擴展功能能夠支持國際化的實現,爲開發多語言版本的應用提供服務。
  2. 繼承ResourcePattemResolver接口,ApplicationContext能夠訪問資源,具體體如今Reource和ResourceLoader的支持上,這樣咱們能夠從不一樣的地方獲得Bean定義的資源。上面咱們所說的XmlBeanFactory中Resource resource=new ClassPathResource("spring-mvc.xml");其實是直接實例化Resource,在ApplicationContext子類中咱們使用Resource getResource(String location);這個方法來使得容器加載資源,不管是類路徑仍是文件路徑均可以識別。若是寫類路徑就和咱們直接實例化ClassPathResource使用同一個類。
  3. 支持應用事件,繼承了ApplicationEventPublisher接口,從而在上下文中引入了事件機制,這些事件機制和Bean的生命週期的結合爲Bean的管理提供了便利
  4. 在ApplicationContext中提供的附加服務,這些服務使得基本的ioc容器的功能更加豐富,使得ApplicationContext與簡單的BeanFactory相比,對它的使用是一種面向框架的使用風格,因此通常建議在開發應用時使用ApplicationContext做爲ioc容器的基本形式。

DefaultListableBeanFactory相關類功能介紹

幾乎全部的beanFactory都是以DefaultListableBeanFactory爲基類或者持有該類來做爲ioc容器所以有必要了解相關類的做用

——AliasRegistry:公用的別名管理接口

——SimpleAliasRegistry別名公用管理的簡單實現類,基本上關於BeanRegistry的實現類都會繼承該類

——BeanDefinitionRegistry持有bean定義的接口,一般由內部是AbstractBeanDefinition層次結構的beanFactory實現,如:DefaultListableBeanFactory

——SingletonBeanRegistry手動註冊單例對象的接口,通常不推薦使用,由於沒有spring官方說這是不被正式支持的,這樣作可能會引發併發訪問異常,在容器中的與/或狀態不一致

——BeanFactory是spring bean容器的根接口,包含全部bean容器基本的操做,如getBean

——DefaultSingletonBeanRegistry繼承SimpleAliasRegistry類,實現了SingletonBeanRegistry接口的類,所以就是一個默認的手動註冊單例對象的實現類,增長了對別名的管理

——HierarchicalBeanFactory代表這些bean是有繼承關係的一個接口

——ListableBeanFactory定義了一些獲取有類似屬性的bean列表

——FactoryBeanRegistrySupport支持基類的單例註冊而且對DefaultSingletonBeanRegistry的一些單例進行管理,還能夠處理一些FactoryBean的操做

——ConfigurableBeanFactory在基類的基礎上添加一些對beanFactory的一些配置

——AbstractBeanFactory是一個徹底實現了ConfigurableBeanFactory的,可做爲擁有bean定義,獲取後端資源功能的beanFactory的實現類的基類的抽象類

——AutowireCapableBeanFactory是一個擴展beanFctory的接口由可以自動裝配的beanFactory實現,前提是他們要爲現有的bean實例開放此功能

——AbstractAutowireCapableBeanFactory抽象beanFactory的父類,實現了缺省bean的建立和AutowireCapableBeanFactory接口的方法以及AbstractBeanFactory的createBean(java.lang.Class<T>)方法 ,擁有RootBeanDefinition類的完整功能,

——ConfigurableListableBeanFactory配置接口由大多數可列出的beanFactory實現,除了ConfigurableBeanFactory外它還提供一些能夠分析修改bean定義以及單例預實例化的工具

——DefaultListableBeanFactory是ListableBeanFactory和BeanDefinitionRegistry接口的默認實現,基於bean 定義對象的beanFactory的完整實現

相關文章
相關標籤/搜索