1. 程式人生 > 實用技巧 >Spring中的BeanFactory

Spring中的BeanFactory

1、Spring中的BeanFactory

1.1、BeanFactory類檢視

1.2 、工廠詳解

1.2.1、BeanFactory
BeanFactory 中定義的各種方法如上面方法註釋,整個設計還是比較簡潔、直觀的,其中將近一半是獲取 bean 物件的各種方法,另外就是對 bean 屬性的獲取和判定,該介面僅僅是定義了 IoC 容器的最基本基本形式,具體實現都交由子類來實現。
1.2.2 、HierarchicalBeanFactory
HierarchicalBeanFactory 譯為中文是“分層的”,它相對於 BeanFactory 增加了對父BeanFactory 的獲取,子容器可以通過介面方法訪問父容器,讓容器的設計具備了層次性。這種層次性增強了容器的擴充套件性和靈活性,我們可以通過程式設計的方式為一個已有的容器新增一個或多個子容器,從而實現一些特殊功能。層次容器有一個特點就是子容器對於父容器來說是透明的,而子容器則能感知到父容器的存在。典型的應用場景就是 Spring MVC,控制層的 bean 位於子容器中,並將業務層和持久層的 bean 所在的容器設定為父容器,這樣的設計可以讓控制層的 bean 訪問業務層和持久層的 bean,反之則不行,從而在容器層面對三層軟體結構設計提供支援。
1.2.3 、ListableBeanFactory
ListableBeanFactory 引入了獲取容器中 bean 的配置資訊的若干方法,比如獲取容器中 bean 的個數,獲取容器中所有 bean 的名稱列表,按照目標型別獲取 bean 名稱,以及檢查容器中是否包含指定名稱的 bean 等等。Listable 中文譯為“可列舉的”,對於容器而言,bean 的定義和屬性是可以列舉的物件。
1.2.4 、AutowireCapableBeanFactory
AutowireCapableBeanFactory 提供了建立 bean、自動注入,初始化以及應用 bean 的後置處理器等功能。自動注入讓配置變得更加簡單,也讓註解配置成為可能,Spring 提供了四種自動注入型別:
     byName:
       根據名稱自動裝配。假設 bean A 有一個名為 b 的屬性,如果容器中剛好存在一個 bean的名稱為 b,則將該 bean 裝配給 bean A 的 b 屬性。
     byType:
       根據型別自動匹配。假設 bean A 有一個型別為 B 的屬性,如果容器中剛好有一個 B 型別的 bean,則使用該 bean 裝配 A 的對應屬性。
     constructor:
        僅針對構造方法注入而言,類似於 byType。如果 bean A 有一個構造方法,構造方法包含一個 B 型別的入參,如果容器中有一個 B 型別的 bean,則使用該        bean 作為入參,如果找不到,則丟擲異常。
     autodetect:
        根據 bean 的自省機制決定採用 byType 還是 constructor 進行自動裝配。如果bean 提供了預設的建構函式,則採用 byType,否則採constructor。
總結:
   <beans/> 元素標籤中的 default-autowire 屬性可以配置全域性自動匹配,default-autowire 預設值為 no,表示不啟用自動裝配。在實際開發中,XML 配置方    式很少啟用自動裝配功能,而基於註解的配置方式預設採用 byType 自動裝配策略。
1.2.5 、ConfigurableBeanFactory
ConfigurableBeanFactory 提供配置 Factory 的各種方法,增強了容器的可定製性,定義了設定類裝載器、屬性編輯器、容器初始化後置處理器等方法。
1.2.6 、DefaultListableBeanFactory
DefaultListableBeanFactory 是一個非常重要的類,它包含了 IoC 容器所應該具備的重要功能,是容器完整功能的一個基本實現,XmlBeanFactory 是一個典型的由該類派生出來的 Factory,並且只是增加了載入 XML 配置資源的邏輯,而容器相關的特性則全部由 DefaultListableBeanFactory 來實現
1.2.7 、ApplicationContext
ApplicationContext 是 Spring 為開發者提供的高階容器形式,也是我們初始化 Spring 容器的常用方式,除了簡單容器所具備的功能外,ApplicationContext 還提供了許多額外功能來降低開發人員的開發量,提升框架的使用效率。這些額外的功能主要包括:
國際化支援:
    ApplicationContext 實現了 org.springframework.context.MessageSource介面,該介面為容器提供國際化訊息訪問功能,支援具備多語言版本需求的應用開發,並提供了多種實現來簡化國際化資原始檔的裝載和獲取。
釋出應用上下文事件:
    ApplicationContext 實現了org.springframework.context.ApplicationEventPublisher 介面,該介面讓容器擁有釋出應用
上下文事件的功能,包括容器啟動、關閉事件等,如果一個 bean 需要接收容器事件,則只需要實現ApplicationListener 介面即可,Spring 會自動掃描對應的監聽器配置,並註冊成為主題的觀察者。
豐富的資源獲取的方式:
    ApplicationContext 實現了org.springframework.core.io.support.ResourcePatternResolver 介面,ResourcePatternResolver 的實現類 PathMatchingResourcePatternResolver 讓我們可以採用Ant 風格的資源路徑去載入配置檔案。
1.2.8 、ConfigurableApplicationContext
ConfigurableApplicationContext 中主要增加了 refresh 和 close 兩個方法,從而為應用上下文提供了啟動、重新整理和關閉的能力。其中 refresh 方法是高階容器的核心方法,方法中概括了高階容器初始化的主要流程(包含簡單的容器的全部功能,以及高階容器特有的擴充套件功能)
1.2.9 、WebApplicationContext
WebApplicationContext 是為 WEB 應用定製的上下文,可以基於 WEB 容器來實現配置檔案的載入,以及初始化工作。對於非 WEB 應用而言,bean 只有 singleton 和 prototype 兩種作用域,而在WebApplicationContext 中則新增了 request、session、globalSession,以及 application四種作用域。

WebApplicationContext 將整個應用上下文物件以屬性的形式放置到 ServletContext 中,所以在WEB 應用中,我們可以通過 WebApplicationContextUtils 的getWebApplicationContext(ServletContext sc) 方法,從 ServletContext 中獲取到
ApplicationContext 例項。為了支援這一特性,WebApplicationContext 定義了一個常量:ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() +".ROOT".

並在初始化應用上下文時以該常量為 key,將 WebApplicationContext 例項存放到 ServletContext的屬性列表中,當我們在呼叫WebApplicationContextUtils 的getWebApplicationContext(ServletContext sc) 方法時,本質上是在呼叫 ServletContext 的getAttribute(String name) 方法,只不過 Spring 會對獲取的結果做一些校驗。
1.2.10 、高階容器的一些具體實現型別
AnnotationConfigApplicationContext:
是基於註解驅動開發的高階容器類,該類中提供了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner兩個成員,AnnotatedBeanDefinitionReader用於讀取註解建立Bean的定義資訊,ClassPathBeanDefinitionScanner負責掃描指定包獲取Bean的定義資訊。

ClasspathXmlApplicationContext:
是基於xml配置的高階容器類,它用於載入類路徑下配置檔案。

FileSystemXmlApplicationContext:
是基於xml配置的高階容器類,它用於載入檔案系統中的配置檔案。

AnnotationConfigWebApplicationContext:
是註解驅動開發web應用的高階容器類。