BeanFactory是Spring中非常重要的一個類,搞懂了它,你就知道了bean的初始化和摧毀過程,對於深入理解IOC有很大的幫助。
BeanFactory體系結構
首先看一下使用IDEA生成的繼承層次圖(圖中去掉了ApplicationContext的繼承圖):
可以看到BeanFactory
下的介面主要分為三個:
HierarchicalBeanFactory
:詳細的分析見https://www.cnblogs.com/zhangfengxian/p/11086695.html#hierarchicalbeanfactoryListableBeanFactory
:詳細的分析見https://www.cnblogs.com/zhangfengxian/p/11086695.html#listablebeanfactoryAutowireCapableBeanFactory
:能夠自動裝配的bean的工廠需要實現此介面,下面會進行詳細的說明。
關於BeanFactory
的分析見https://www.cnblogs.com/zhangfengxian/p/11086695.html#beanfactory
BeanFactory介面分析
下面將對BeanFactory
中的介面進行分析。
AutowireCapableBeanFactory
該介面提供了對現有bean進行自動裝配的能力,設計目的不是為了用於一般的應用程式碼中,對於一般的應用程式碼應該使用BeanFactory
和ListableBeanFactory
。其他框架的程式碼整合可以利用這個介面去裝配和填充現有的bean的例項,但是Spring不會控制這些現有bean的生命週期。你也許注意到了ApplicationContext
中的getAutowireCapableBeanFactory()
能獲取到AutowireCapableBeanFactory
的例項(https://www.cnblogs.com/zhangfengxian/p/11086695.html#applicationcontext%E8%AE%BE%E8%AE%A1%E8%A7%A3%E6%9E%90)。同樣,也能實現BeanFactoryAware
介面來接收BeanFactory
(應用程式上下暴露的內部使用的BeanFactory)的例項,然後將其轉換成AutowireCapableBeanFactory
。
下面看一下這個介面中的靜態成員變數和方法:
// 定義了bean的裝配策略
int AUTOWIRE_NO = 0; // 不進行裝配
int AUTOWIRE_BY_NAME = 1; // 根據名字進行裝配
int AUTOWIRE_BY_TYPE = 2; // 根據型別進行裝配
int AUTOWIRE_CONSTRUCTOR = 3; // 根據建構函式進行裝配
@Deprecated
int AUTOWIRE_AUTODETECT = 4; // Spring3.0已經過時的方法,通過省視bean來決定適當的裝載策略
//Spring5.1後增加,原始例項的字尾,例如"com.mypackage.MyClass.ORIGINAL",強制返回給定的例項(沒有代理)
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
// 完全建立給定類的一個新的例項,包括所有適用的BeanPostProcessor
// 填充註解的field和方法,並且會應用所有的初始化回撥函式
<T> T createBean(Class<T> beanClass) throws BeansException;
// 裝配bean,通過應用初始化之後的回撥函式和bean屬性的後置處理來填充給定的bean的例項
// 本質上是為了在建立新的例項或者反序列化例項時,填充(重新填充)例項中註解的field和方法
void autowireBean(Object existingBean) throws BeansException;
// 配置給定的原始bean:自動裝配bean的屬性,應用bean的屬性值、工廠回撥函式(例如setBeanName,values)
// 同樣也會應用所有bean的後置處理器
Object configureBean(Object existingBean, String beanName) throws BeansException;
// 使用指定的裝配策略來完全建立一個新的bean的例項
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
// 使用指定的裝配策略來例項化一個給定類新的bean的例項
// 不會應用標準的BeanPostProcessor回撥函式或者在未來執行任何bean的初始化
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
// 根據名字和型別來自動裝配給定bean的例項的屬性
// 不會應用標準的BeanPostProcessor回撥函式或者在未來執行任何bean的初始化
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
// 應用給定名字的bean的定義的屬性值到給定的bean的例項
// 該方法不會自動裝配bean屬性,僅僅應用明確定義的屬性值
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
// 初始化給定的原始的bean應用bean的屬性值、工廠回撥函式(例如setBeanName,values)
// 同樣也會應用所有bean的後置處理器
Object initializeBean(Object existingBean, String beanName) throws BeansException;
// 應用BeanPostProcessor到給定的現存的bean的例項,呼叫postProcessBeforeInitialization方法
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
// 應用BeanPostProcessor到給定的現存的bean的例項,postProcessAfterInitialization
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
// 摧毀給定的bean的例項,應用DisposableBean規約和註冊的DestructionAwareBeanPostProcessor
void destroyBean(Object existingBean);
// 解析唯一匹配給定物件型別的bean的例項,該方法是getBean(Class)的變種,只不過它還提供了匹配例項的bean的名字
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
// 解析給定bean的名字的例項,提供了用於暴露目標的工廠方法的依賴描述符
Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
// 針對在工廠中定義的bean來解析指定的依賴
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
// 針對在工廠中定義的bean來解析指定的依賴
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
ConfigurableBeanFactory
ConfigurableBeanFactory
提供了bean工廠的配置機制(除了BeanFactory介面中的bean的工廠的客戶端方法)。該BeanFactory介面不適應一般的應用程式碼中,應該使用BeanFactory
和ListableBeanFactory
。該擴充套件介面僅僅用於內部框架的使用,並且是對bean工廠配置方法的特殊訪問。
ConfigurableBeanFactory
繼承自HierarchicalBeanFactory
和SingletonBeanRegistry
,下面先看下SingletonBeanRegistry
:
SingletonBeanRegistry
是為了共享的bean的例項而定義的註冊器,以統一的方式暴露單例管理機制。下面是在此介面中定義的方法:
// 在bean的註冊器中以給定的bean的名字將給定的現存物件註冊為單例
void registerSingleton(String beanName, Object singletonObject);
// 根據給定的bean的名字來獲取單例bean,可能為null
Object getSingleton(String beanName);
// 是否包含給定名字的單例bean
boolean containsSingleton(String beanName);
// 獲取所有在註冊器中註冊的單例bean的名字
String[] getSingletonNames();
// 獲取所有在註冊器中註冊的單例bean的數量
int getSingletonCount();
// 獲取在這個註冊器中使用的單例的mutex(用於外部協同)
Object getSingletonMutex();
需要注意的是使用registerSingleton
方法註冊的單例bean,不會執行任何的初始化回撥函式(尤其不會呼叫InitializingBean
的afterPropertiesSet
方法),同樣也不會接收任何的摧毀回撥函式。如果需要接收初始化和摧毀回撥函式,請註冊bean的定義而不是現存的例項物件。
接下來看下ConfigurableBeanFactory
中定義的方法:
// 作用域
String SCOPE_SINGLETON = "singleton"; // 單例作用域
String SCOPE_PROTOTYPE = "prototype"; // 原型作用域
// 設定父級bean工廠
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
// 設定bean的類載入器,預設為執行緒上下文類載入器
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
// 獲取bean的類載入器
@Nullable
ClassLoader getBeanClassLoader();
// 設定臨時的類載入器
void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
// 獲取臨時的類載入器
@Nullable
ClassLoader getTempClassLoader();
// 設定是否快取bean的後設資料
void setCacheBeanMetadata(boolean cacheBeanMetadata);
// 是否快取bean的後設資料
boolean isCacheBeanMetadata();
// 設定bean的表示式解析器,以統一的EL相容樣式支援#{...}這樣的表示式
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
// 獲取bean的表示式解析器
@Nullable
BeanExpressionResolver getBeanExpressionResolver();
// 設定轉換服務,用於轉換屬性值
void setConversionService(@Nullable ConversionService conversionService);
// 獲取轉換服務
@Nullable
ConversionService getConversionService();
// 新增屬性編輯器註冊者
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
// 為所有給定的屬性註冊自定義屬性編輯器
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
// 使用在BeanFactory中註冊的自定義編輯器來初始哈給定的屬性編輯器註冊者
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
// 設定型別轉換器
void setTypeConverter(TypeConverter typeConverter);
// 獲取型別轉換器
TypeConverter getTypeConverter();
// 新增嵌入值解析器,例如註冊屬性
void addEmbeddedValueResolver(StringValueResolver valueResolver);
// 在BeanFactory是否有註冊嵌入值解析器
boolean hasEmbeddedValueResolver();
// 解析給定的嵌入的值
@Nullable
String resolveEmbeddedValue(String value);
// 新增bean的後置處理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
// 獲取bean的後置處理器個數
int getBeanPostProcessorCount();
// 註冊作用域
void registerScope(String scopeName, Scope scope);
// 獲取註冊的作用域的名字
String[] getRegisteredScopeNames();
// 獲取作用域
@Nullable
Scope getRegisteredScope(String scopeName);
// 提供一個與這個工廠有關的安全訪問控制上下文
AccessControlContext getAccessControlContext();
// 從給定的其他的工廠拷貝所有相關的配置。不應該包含任何bean的定義後設資料
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
// 註冊別名
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
// 解析所有別名的目標名稱和在工廠中註冊的別名,將給定的StringValueResolver應用於它們
void resolveAliases(StringValueResolver valueResolver);
// 獲取合併的bean的定義
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 給定名字的bean是否為FactoryBean
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
// 顯式的設定指定bean的目前在建立狀態
void setCurrentlyInCreation(String beanName, boolean inCreation);
// 指定的bean目前是否為在建狀態
boolean isCurrentlyInCreation(String beanName);
// 註冊給定bean所依賴的bean
void registerDependentBean(String beanName, String dependentBeanName);
// 獲取所有依賴於指定bean的bean的名字
String[] getDependentBeans(String beanName);
// 獲取所有指定bean所依賴的bean的名字
String[] getDependenciesForBean(String beanName);
// 根據bean的定義來摧毀給定的bean的例項(通常是從工廠中獲取到的原型例項)
void destroyBean(String beanName, Object beanInstance);
// 在當前目標作用域中摧毀指定的作用域中的bean
void destroyScopedBean(String beanName);
// 摧毀在工廠中的所有單例bean
void destroySingletons();
上面的大部分方法都是獲取或者設定一些配置的資訊,以便協同來完成BeanFactory的配置。
ConfigurableListableBeanFactory
ConfigurableListableBeanFactory
介面繼承自ListableBeanFactory
, AutowireCapableBeanFactory
, ConfigurableBeanFactory
。大多數具有列出能力的bean工廠都應該實現此介面。此了這些介面的能力之外,該介面還提供了分析、修改bean的定義和單例的預先例項化的機制。這個介面不應該用於一般的客戶端程式碼中,應該僅僅提供給內部框架使用。下面是這個介面的方法:
// 忽略用於自動裝配的依賴的型別
void ignoreDependencyType(Class<?> type);
// 忽略用於自動裝配的依賴的介面
void ignoreDependencyInterface(Class<?> ifc);
// 給特定的依賴型別註冊自動裝配的值
void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
// 指定的bean是否為自動裝配的候選者
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
// 獲取bean的定義
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 獲取這個工廠中的所有bean的名字的迭代器
Iterator<String> getBeanNamesIterator();
// 清除後設資料快取
void clearMetadataCache();
// 凍結所有bean的定義
void freezeConfiguration();
// 工廠中bean的定義是否凍結了
boolean isConfigurationFrozen();
// 對非懶載入的單例進行預先初始化
void preInstantiateSingletons() throws BeansException;
AbstractBeanFactory
AbstractBeanFactory
繼承自FactoryBeanRegistrySupport
,實現了ConfigurableBeanFactory
介面。AbstractBeanFactory
是BeanFactory
的抽象基礎類實現,提供了完整的ConfigurableBeanFactory
的能力。在這裡不討論該抽象類的實現細節,只要知道這個類是幹什麼的就行了,會面會有更加詳細的章節來討論。
- 單例快取
- 別名的管理
- FactoryBean的處理
- 用於子bean定義的bean的合併
- bean的摧毀介面
- 自定義的摧毀方法
- BeanFactory的繼承管理
子類需要實現的模板方法如下:
// 是否包含給定名字的bean的定義
protected abstract boolean containsBeanDefinition(String beanName);
// 根據bean的名字來獲取bean的定義,子類通常要實現快取
protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
// 為給定的已經合併了的bean的定義建立bean的例項
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException;
AbstractAutowireCapableBeanFactory
AbstractAutowireCapableBeanFactory
繼承自AbstractBeanFactory
,實現了AutowireCapableBeanFactory
介面。該抽象了實現了預設的bean的建立。
- 提供了bean的建立、屬性填充、裝配和初始化
- 處理執行時bean的引用,解析管理的集合、呼叫初始化方法等
- 支援構造器自動裝配,根據型別來對屬性進行裝配,根據名字來對屬性進行裝配
子類需要自行實現的模板方法如下:
// 用於根據型別來進行自動裝配
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
DefaultListableBeanFactory
DefaultListableBeanFactory
繼承自AbstractAutowireCapableBeanFactory
,實現了ConfigurableListableBeanFactory
, BeanDefinitionRegistry
, Serializable
介面。這個類是一個非常完全的BeanFactory,基於bean的定義後設資料,通過後置處理器來提供可擴充套件性。
XmlBeanFactory
XmlBeanFactory
繼承自DefaultListableBeanFactory
,用來從XML文件中讀取bean的定義的一個非常方便的類。最底層是委派給XmlBeanDefinitionReader
,實際上等價於帶有XmlBeanDefinitionReader
的DefaultListableBeanFactory
。