天天看點

Spring-Bean包分析Spring Beans

我的個人網址: zidot.cn

Spring Beans

包概述

spring beans 包主要用來處理Spring Bean,包括Bean的容器定義、Bean的生命周期、Bean的初始化、Bean配置加載等。spring 提供了三種Bean的配置方式,包括xml配置、Java config配置、groovy配置。

結構圖

spring-beans 下主要包含annotation、factory、propertyeditors、support包。最主要的是factory、propertyeditors包了。我精心整理了包下關鍵的接口或類,并繪制了類圖。如下圖

spring-beans 包結構:

Spring-Bean包分析Spring Beans

其中有幾個核心的類,如下:

  • BeanInfoFactory
  • ExtendedBeanInfo
  • BeanWrapper
BeanInfoFactory

BeanInfoFactory 是BeanInfo 工廠類,用來生成指定的Bean Class的描述類BeanInfo。BeanInfoFactory的實作類是ExtendedBeanInfoFactory,其中getBeanInfo方法放回的其實是ExtendedBeanInfo執行個體。有一點要注意ExtendedBeanInfoFactory 中的getBeanInfo 每次傳回的是新的BeanInfo對象,内部沒有作緩存。

那BeanInfo是用來做什麼的呢。其實BeanInfo,是在java.beans包下,是java标準的一個接口。用來描述Iava Bean的一些資訊。我們可以通過java 提供的 Introspector#getBeanInfo 方法擷取指定類的的BeanInfo執行個體。

ExtendedBeanInfo

ExtendedBeanInfo 采用了代理模式,繼承了BeanInfo接口,持有一個BeanInfo執行個體的引用。

BeanWrapper

BeanWrapper 是Spring Bean的包裝類,通過它我們可以非常友善的通路Bean的屬性、擷取某個屬性的值或給某個屬性指派。Spring 還提供了強大的類型轉換機制,在給Bean屬性指派時,進行對應的類型轉換工作,這個轉換是由TypeConverter來定義并由AbstractNestablePropertyAccessor類實作。

對Bean屬性的通路、指派是通過PropertyAccessor來實作的。PropertyAccessor 支援嵌套的屬性通路和數組通路,我們可以用路徑來表式一個屬性,如:“foo.bar”,“person.addresses[0]”。這種嵌套的屬性路徑有可能出現父一級為null的情況,這種情況下spring為我們提供了兩種處理方式,一:如果父一級為null,spring 幫我們自動建立一個父級對象;二:抛出NullValueInNestedPathException 異常。spring 把這種特性叫 auto-grow。可以通過ConfigurablePropertyAccessor#setAutoGrowNestedPaths方法設定是否開啟,預設關閉。

在BeanWrapper接口中還有一個方法跟 auto-grow有關,它就是BeanWrapper#setAutoGrowCollectionLimit 方法。它是用來控制auto-grow開啟下,如果父一級是數組或集合的話,auto-grow 對生成的數組元素個數的限制,預設是沒有限制的。如,我通過 “person.addresses[1]” 來給person對象中的addresses數組種的元素指派,在auto-grow開啟的情況下如果通路的下表元素不存在spring會幫我們建立一個。假如數組下标值很大,spring就或建立一個很大的數組來容納這個元素。setAutoGrowCollectionLimit方法就是用來控制這個的,我們可以控制要建立的元素個數不能超過某個值。

TypeConverter類型轉換具體的實作是通過 ConversionService,ConversionService是在Spring-Core中定義一個服務接口。Spring為我們提供了很好的擴充支援。如果進行擴充,我會在其他地方寫到。

factory 結構圖

前面提到了spring 提供了三種Bean的配置方式,包括xml配置、Java config配置、groovy配置。這麼強大的能力都是在factory包中實作的。由于内容比較多各個配置的代碼是如何實作的,我會在其他的章節詳細講解。下邊主要介紹BeanFactory、Bean聲明周期相關的一些類。

spring-beans 子包factory包結構:圖中顔色部分一般用在Bean上。

Spring-Bean包分析Spring Beans

其中有幾個核心的類,如下:

  • BeanFacotry
  • Aware
  • FactoryBean
BeanFactory

BeanFactory 就是我們經常講的Bean 容器。BeanFactory為我們提供了幾個常見的擷取Bean的方法,如通過名字、類型、别名來擷取Bean。BeanFactory 是支援父子容器的。提到父子容器,我們首先想到的大概就是Spring MVC了吧。

Aware

Aware 接口隻是一個辨別接口。factory下有BeanClassLoaderAware、BeanFactoryAware、BeanNameAware。比較常用的是BeanFactoryAware,用來注入BeanFacotry。

FactoryBean

FactoryBean是一種特殊接口,我們可以叫他工廠Bean。它首先是一個Spring Bean,然後是一個工廠。那麼這個工廠用來做什麼的呢,它是用來生成Spring Bean的。如果一個Bean 實作了該接口,就不能想普通的Bean一樣來使用。我們通過名字擷取到的Bean執行個體都是通過工廠來生成的。如果我要擷取FactoryBean的執行個體怎麼辦呢,我們可以在BeanName請加上“&”符号。例如:BeanFactory.getBean("&delegator");

DisposableBean
InitializingBean
SmartInitializingSingleton

可以在Bean周期中的回調接口,通過實作某個接口可以參與到Bean的整個過程中來,從Bean的建立到銷毀。