本文主要介紹BeanFactory以及它的各種繼承層級的接口、抽象類及實現類,因為內容很多,所以這里不介紹ApplicationContext繼承體系下的類(雖然ApplicationContext本質上也是BeanFactory,但是畢竟這這是我們平時接觸最多的兩種類別,所以分開說)。
關于ApplicationContext繼承體系結構在《Spring IOC-ApplicationContext的繼承體系結構》一文分享說明。
BeanFactory其實就是Spring的IOC容器,當然了Spring為我們準備了許多種IOC容器來使用,這樣可以方便我們從不同的層面,不同的資源位置,不同的形式的定義信息來建立我們需要的IoC容器。
在鄙人博客的不同的博文中其實都提到了Spring的一個設計理念,就是接口-抽象類-實現類的體系結構,這里多說幾句為什么這么設計,熟悉設計模式的人都知道,這樣的目的是為了提高軟件的可維護性、可擴展性、強復用性。說的文雅一點就是使代碼滿足“對修改關閉、對擴展開放”、“里氏代換”原則 、“依賴倒轉”原則、“接口隔離”原則、“合成\聚合復用”原則。如果項了解這幾個原則可以百度下,這里不詳細介紹。
廢話不多說,直接上代碼來看下BeanFactory的繼承道理多屌。
先貼張圖,大家大致看下知道下面介紹的類大概在繼承體系的哪個位置。
首先看BeanFactory接口中定義的方法:
public interface BeanFactory {//這里是對FactoryBean的轉義定義,因為如果使用bean的名字檢索FactoryBean得到的對象是工廠生成的對象String FACTORY_BEAN_PREFIX = "&";//這里根據bean的名字,在IOC容器中得到bean實例,這個IOC容器就是一個大的抽象工廠。 Object getBean(String name) throws BeansException;//這里根據bean的名字和Class類型來得到bean實例,和上面的方法不同在于它會拋出異常:如果根據名字取得的bean實例的Class類型和需要的不同的話。<T> T getBean(String name, Class<T> requiredType);<T> T getBean(Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;//這里提供對bean的檢索,看看是否在IOC容器有這個名字的beanboolean containsBean(String name);//這里根據bean名字得到bean實例,并同時判斷這個bean是不是單件 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;//這里根據bean名字得到bean實例,并同時判斷這個bean是不是原型 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;//這里對得到bean實例的Class類型 Class<?> getType(String name) throws NoSuchBeanDefinitionException;//這里得到bean的別名,如果根據別名檢索,那么其原名也會被檢索出來 String[] getAliases(String name);
然后在看BeanFactory 的直接繼承接口(二級接口),有HierarchicalBeanFactory、AutowireCapableBeanFactory和ListableBeanFactory看這三個類代碼:
HierarchicalBeanFactory
作用:是為了實現bean工廠的層級關系提供支持,其中聲明兩個方法:
//得到父工廠
BeanFactory getParentBeanFactory();
//在本地工廠中有沒有給定名稱的bean,不包括繼承的工廠
boolean containsLocalBean(String name);
AutowireCapableBeanFactory
作用:提供自動裝配bean能力的功能支持,聲明方法如下:(這個接口中所有聲明的方法都是在默認的實現實在AbstractAutowireCapableBeanFactory類中默認實現)
//用個給定的class類型制造一個完整的bean
<T> T createBean(Class<T> beanClass) throws BeansException;
//bean初始化完成之后執行回調函數和后處理器,
void autowireBean(Object existingBean) throws BeansException;
// 自動注入和設置bean的屬性、執行factory回調函數比如setBeanName和setBeanFactory和執行bean的所有的后處理器
Object configureBean(Object existingBean, String beanName) throws BeansException;
//調用bean的init方法,這個方法是客戶配置的,在bean實例化之后調用
Object initializeBean(Object existingBean, String beanName) throws BeansException;
//初始化完成之后應用后處理器
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
//應用前處理器
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName);
ListableBeanFactory
作用:可以枚舉所有的bean實例,是為了使客戶端訪問工廠中的bean而設計的,主要方法(這些方法顧名思義,所有的方法實現在StaticListableBeanFactory、AbstractApplicationContext和DefaultListableBeanFactory中):
//是否含有給定的名稱的bean
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
//得到工廠所有的bean的名稱數組
String[] getBeanDefinitionNames();
String[] getBeanNamesForType(Class<?> type);
//根據給定的類型得到和相應的策略得到所有的bean名稱數組
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
//根據給定過的類型得到所有該類型的bean,返回的結果是一個Map<bean名稱,bean對象>的形式
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
//得到給定名稱的bean上的給定注解類型的注解對象
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
下面我們介紹BeanFactory 的三級接口,看繼承關系圖知道是ConfigurableBeanFactory和ConfigurableListableBeanFactory。
ConfigurableBeanFactory
作用: 實現可配置的bean的環境功能,這個接口繼承自HierarchicalBeanFactory所以支持層級關系的工廠,和SingletonBeanRegistry所以肯定支持單例工廠行為,看主要方法代碼(在AbstractBeanFactory類中默認實現):
void setConversionService(ConversionService conversionService);
void setTypeConverter(TypeConverter typeConverter);
//支持自定義bean的作用范圍,可以理解為單例和多例之外的
void registerScope(String scopeName, Scope scope);
//歸并的將給定的name的bean的定義
BeanDefinition getMergedBeanDefinition(String beanName);
//添加處理器
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
//下面是3個destory方法
void destroyBean(String beanName, Object beanInstance);
void destroyScopedBean(String beanName);
//只能銷毀所有單例的bean,因為多例的是不歸Spring控制的,是由客戶端控制的
void destroySingletons();
ConfigurableListableBeanFactory
作用:提供可配置的、可訪問的功能,接口中的方法在在DefaultListableBeanFactory默認實現默認實現。
public interface ConfigurableListableBeanFactoryextends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {//凍住之后bean定義就不能在被修改和進行任何的后處理器規定的操作void freezeConfiguration();//確保所有的單例bean都實例化void preInstantiateSingletons() throws BeansException;//BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;//判斷當前的bean是不是作為其它bean的依賴注入的boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor);
上面是接口的繼承體系和說明,下面來介紹接口下抽象類的代碼,在上面的介紹中我們知道就兩個抽象類AbstractAutowireCapableBeanFactory和AbstractBeanFactory,先看繼承關系:
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactoryimplements AutowireCapableBeanFactory {
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
可以知道AbstractAutowireCapableBeanFactory 是AbstractBeanFactory 類的子類。通過上面的接口和抽象類的介紹我們將研究的重點轉到轉到這兩個抽象類中。
這里我們主要看bean工廠是怎么將xml中的定義信息轉換為互相依賴的bean定義或者初始化為實體對象。
先看在繼承體系偏上的類AbstractBeanFactory ,這個類最重要的是對BeanFactory中getBean()的實現,直接看實現的代碼:
………………
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {return doGetBean(name, requiredType, args, false);
}
在看doGetBean()方法代碼:
………………
//首先從單例工廠得到有沒有
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//不是但單例的
else {//看是不是在父BeanFactory ,因為實現了HierarchicalBeanFactory接口BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {return parentBeanFactory.getBean(nameToLookup, requiredType);}
……………………if (mbd.isSingleton()) {//單例的//用回調的形式建造bean并且放入單例工廠sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {public Object getObject() throws BeansException {try {return createBean(beanName, mbd, args);}……………………//多例的else if (mbd.isPrototype()) {Object prototypeInstance = null;beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);………………else {//沒有明確是單例的還是不是,有自己的作用域scopeString scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {public Object getObject() throws BeansException { return createBean(beanName, mbd, args);……………………
可以上面是分為三種情況得到bean的,單例的、多例的、Scope的。但是所有的情況最終都定位到一個方法——createBean(beanName, mbd, args),這個方法在AbstractBeanFactory 是抽象的protected abstract Object createBean(,很明顯,只能在子類中實現,自然就要看AbstractAutowireCapableBeanFactory 中的建造bean的createBean()代碼:
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)throws BeanCreationException {………………//如果沒有找到這個name的class類型是會拋出異常的resolveBeanClass(mbd, beanName);//判斷在xml中定義的overrides方法存在mbd.prepareMethodOverrides();………………//用bean的前處理器去實例化Object bean = resolveBeforeInstantiation(beanName, mbd);………………Object beanInstance = doCreateBean(beanName, mbd, args);………………
好的,代碼定位到**doCreateBean(beanName, mbd, args)**方法:
//逐漸的構造一個bean,分別用factory method, and autowiring a constructor.去構造,這些都是在xml中配置的。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {………………instanceWrapper = createBeanInstance(beanName, mbd, args);………………//構造bean并且注入依賴所有bean的屬性值Object exposedObject = bean;try {populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {//調用配置的init方法exposedObject = initializeBean(beanName, exposedObject, mbd);} }
代碼定位到createBeanInstance(beanName, mbd, args)
//用 factory method, constructor autowiring, or simple instantiation.三種方法去實例化一個bean
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {………………//用getFactoryMethodName去實例化一個if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}………………//用構造函數if (autowireNecessary) {return autowireConstructor(beanName, mbd, null, null);}else {//用默認的構造函數得到return instantiateBean(beanName, mbd);}………………
}
再定位代碼到populateBean(beanName, mbd, instanceWrapper):
//主要是bean中的成員變量的初始化和注入,《依賴的注入》
protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {……………………if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs;
} ……………………//將屬性的引用和具體的對象結合起來,用到了java的反射機制applyPropertyValues(beanName, mbd, bw, pvs);
}
最后是applyPropertyValues(beanName, mbd, bw, pvs)
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {try {//調用BeanWrapper類的方法bw.setPropertyValues(new MutablePropertyValues(deepCopy));}
這里補充一下BeanWrapperImpl類中設置屬性依賴的代碼實現:
………………
//如果有key屬性配置,證明是array list 或者map
if (tokens.keys != null) {if (propValue.getClass().isArray()) {else if (propValue instanceof List) {else if (propValue instanceof Map) {
}
//普通的屬性設置
else{………………writeMethod.setAccessible(true);writeMethod.invoke(object, value);
}
………………
至此bean的如何初始化和如何進行依賴注入就已經研究代碼完畢。
下面也是最后我們看一下這個繼承體系中具體類XmlBeanFactory、DefaultListableBeanFactory的實現代碼:
XmlBeanFactory
//這個類的實現很簡單,只是委托XmlBeanDefinitionReader進行xml的讀取和配置信息的加載
public class XmlBeanFactory extends DefaultListableBeanFactory {private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);// 構造的時候就進行xml文件的解析public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {super(parentBeanFactory);this.reader.loadBeanDefinitions(resource);}
}
關于XmlBeanFactory加載xml,會在Spring IOC-XmlBeanFactory如何加載xml及如何存儲轉換后的信息一文介紹。
DefaultListableBeanFactory
是XmlBeanFactory的父類,也就是而你看下文章最前面的繼承圖,你會發現DefaultListableBeanFactory擁有這個繼承體系中的所有功能。
那么除了繼承父類的功能方法外,它獨特的功能在于對ConfigurableListableBeanFactory和ListableBeanFactory接口的實現。