Spring的BeanFactory的繼承體系堪稱經典。這是衆所周知的!做爲Java程序員,不能錯過!html
前面的博文分析了Spring的Resource資源類Resouce。今天開始分析Spring的IOC部分。衆所周知,IOC是Spring框架最迷人的地方。它最重要的接口,就是BeanFactory了。BeanFactory有着龐大的繼承、實現體系,有衆多的子接口、實現類。本博文的目標就是抽絲剝繭,從源代碼入手,分析Spring的實現和架構,從中進步。程序員
在閱讀的過程當中,能夠參照Spring文檔來一塊兒學習:Spring3.1.1文檔spring
本人英文水平有限,部分翻譯可能不恰當,歡迎指出!api
1、BeanFactory的基本類體系結構(接口爲主):緩存
這是我畫的BeanFactory基本的類體系結構,這裏沒有包括強大的ApplicationContext體系,ApplicationContext我準備放到下一篇再分析。安全
具體:架構
一、BeanFactory做爲一個主接口不繼承任何接口,暫且稱爲一級接口。app
二、有3個子接口繼承了它,進行功能上的加強。這3個子接口稱爲二級接口。框架
三、ConfigurableBeanFactory能夠被稱爲三級接口,對二級接口HierarchicalBeanFactory進行了再次加強,它還繼承了另外一個外來的接口SingletonBeanRegistry編輯器
四、ConfigurableListableBeanFactory是一個更強大的接口,繼承了上述的全部接口,無所不包,稱爲四級接口。
(這4級接口是BeanFactory的基本接口體系。繼續,下面是繼承關係的2個抽象類和2個實現類:)
五、AbstractBeanFactory做爲一個抽象類,實現了三級接口ConfigurableBeanFactory大部分功能。
六、AbstractAutowireCapableBeanFactory一樣是抽象類,繼承自AbstractBeanFactory,並額外實現了二級接口AutowireCapableBeanFactory
七、DefaultListableBeanFactory繼承自AbstractAutowireCapableBeanFactory,實現了最強大的四級接口ConfigurableListableBeanFactory,並實現了一個外來接口BeanDefinitionRegistry,它並不是抽象類。
八、最後是最強大的XmlBeanFactory,繼承自DefaultListableBeanFactory,重寫了一些功能,使本身更強大。
總結:
BeanFactory的類體系結構看似繁雜混亂,實際上由上而下層次分明,很是容易理解。
2、IOC的始祖——BeanFactory
來看一下BeanFactory的源碼,這麼牛逼哄哄的接口就不折疊了吧:
package org.springframework.beans.factory; public interface BeanFactory { /** * 用來引用一個實例,或把它和工廠產生的Bean區分開,就是說,若是一個FactoryBean的名字爲a,那麼,&a會獲得那個Factory */ String FACTORY_BEAN_PREFIX = "&"; /* * 四個不一樣形式的getBean方法,獲取實例 */ Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; boolean containsBean(String name); // 是否存在 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 是否爲單實例 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 是否爲原型(多實例) boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;// 名稱、類型是否匹配 Class<?> getType(String name) throws NoSuchBeanDefinitionException; // 獲取類型 String[] getAliases(String name);// 根據實例的名字獲取實例的別名 }
具體:
一、4個獲取實例的方法。getBean的重載方法。
二、4個判斷的方法。判斷是否存在,是否爲單例、原型,名稱類型是否匹配。
三、1個獲取類型的方法、一個獲取別名的方法。根據名稱獲取類型、根據名稱獲取別名。一目瞭然!
總結:
這10個方法,很明顯,這是一個典型的工廠模式的工廠接口。
3、可將Bean逐一列出的工廠——ListableBeanFactory
源碼:
public interface ListableBeanFactory extends BeanFactory { boolean containsBeanDefinition(String beanName); // 對於給定的名字是否含有BeanDefinition int getBeanDefinitionCount(); // 返回工廠的BeanDefinition總數 String[] getBeanDefinitionNames(); // 返回工廠中全部Bean的名字 String[] getBeanNamesForType(Class<?> type); // 返回對於指定類型Bean(包括子類)的全部名字 /* * 返回指定類型的名字 includeNonSingletons爲false表示只取單例Bean,true則不是 * allowEagerInit爲true表示馬上加載,false表示延遲加載。 注意:FactoryBeans都是馬上加載的。 */ String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit); <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; // 根據類型(包括子類)返回指定Bean名和Bean的Map <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException; Map<String, Object> getBeansWithAnnotation( Class<? extends Annotation> annotationType) throws BeansException; // 根據註解類型,查找全部有這個註解的Bean名和Bean的Map <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);// 根據指定Bean名和註解類型查找指定的Bean }
具體:
一、3個跟BeanDefinition有關的整體操做。包括BeanDefinition的總數、名字的集合、指定類型的名字的集合。
(這裏指出,BeanDefinition是Spring中很是重要的一個類,每一個BeanDefinition實例都包含一個類在Spring工廠中全部屬性。)
二、2個getBeanNamesForType重載方法。根據指定類型(包括子類)獲取其對應的全部Bean名字。
三、2個getBeansOfType重載方法。根據類型(包括子類)返回指定Bean名和Bean的Map。
四、2個跟註解查找有關的方法。根據註解類型,查找Bean名和Bean的Map。以及根據指定Bean名和註解類型查找指定的Bean。
總結:
正如這個工廠接口的名字所示,這個工廠接口最大的特色就是能夠列出工廠能夠生產的全部實例。固然,工廠並無直接提供返回全部實例的方法,也沒這個必要。它能夠返回指定類型的全部的實例。並且你能夠經過getBeanDefinitionNames()獲得工廠全部bean的名字,而後根據這些名字獲得全部的Bean。這個工廠接口擴展了BeanFactory的功能,做爲上文指出的BeanFactory二級接口,有9個獨有的方法,擴展了跟BeanDefinition的功能,提供了BeanDefinition、BeanName、註解有關的各類操做。它能夠根據條件返回Bean的集合,這就是它名字的由來——ListableBeanFactory。
4、分層的Bean工廠——HierarchicalBeanFactory
源碼:
public interface HierarchicalBeanFactory extends BeanFactory { BeanFactory getParentBeanFactory(); // 返回本Bean工廠的父工廠 boolean containsLocalBean(String name); // 本地工廠是否包含這個Bean }
具體:
一、第一個方法返回本Bean工廠的父工廠。這個方法實現了工廠的分層。
二、第二個方法判斷本地工廠是否包含這個Bean(忽略其餘全部父工廠)。這也是分層思想的體現。
總結:這個工廠接口很是簡單,實現了Bean工廠的分層。這個工廠接口也是繼承自BeanFacotory,也是一個二級接口,相對於父接口,它只擴展了一個重要的功能——工廠分層。
5、自動裝配的Bean工廠——AutowireCapableBeanFactory
源碼:
public interface AutowireCapableBeanFactory extends BeanFactory { int AUTOWIRE_NO = 0; // 這個常量代表工廠沒有自動裝配的Bean int AUTOWIRE_BY_NAME = 1; //代表根據名稱自動裝配 int AUTOWIRE_BY_TYPE = 2; //代表根據類型自動裝配 int AUTOWIRE_CONSTRUCTOR = 3; //代表根據構造方法快速裝配 @Deprecated int AUTOWIRE_AUTODETECT = 4; //代表經過Bean的class的內部來自動裝配(有沒翻譯錯...)Spring3.0被棄用。 <T> T createBean(Class<T> beanClass) throws BeansException; // 根據指定Class建立一個全新的Bean實例 void autowireBean(Object existingBean) throws BeansException; // 給定對象,根據註釋、後處理器等,進行自動裝配 /* * 根據Bean名的BeanDefinition裝配這個未加工的Object,執行回調和各類後處理器。 */ Object configureBean(Object existingBean, String beanName) throws BeansException; /* * 分解Bean在工廠中定義的這個指定的依賴descriptor */ Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException; /* * 根據給定的類型和指定的裝配策略,建立一個新的Bean實例 */ Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; /* * 與上面相似,不過稍有不一樣。 */ Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; /* * 根據名稱或類型自動裝配 */ void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException; /* * 也是自動裝配 */ void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException; /* * 初始化一個Bean... */ Object initializeBean(Object existingBean, String beanName) throws BeansException; /* * 初始化以前執行BeanPostProcessors */ Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException; /* * 初始化以後執行BeanPostProcessors */ Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException; /* * 分解指定的依賴 */ Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException; }
具體:
一、總共5個靜態不可變常量來指明裝配策略,其中一個常量被Spring3.0廢棄、一個常量表示沒有自動裝配,另外3個常量指明不一樣的裝配策略——根據名稱、根據類型、根據構造方法。
二、8個跟自動裝配有關的方法,實在是繁雜,具體的意義咱們研究類的時候再分辨吧。
三、2個執行BeanPostProcessors的方法。
四、2個分解指定依賴的方法
總結:這個工廠接口繼承自BeanFacotory,它擴展了自動裝配的功能,根據類定義BeanDefinition裝配Bean、執行前、後處理器等。
6、複雜的配置Bean工廠——ConfigurableBeanFactory
源碼:
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry { String SCOPE_SINGLETON = "singleton"; // 單例 String SCOPE_PROTOTYPE = "prototype"; // 原型 /* * 搭配HierarchicalBeanFactory接口的getParentBeanFactory方法 */ void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException; /* * 設置、返回工廠的類加載器 */ void setBeanClassLoader(ClassLoader beanClassLoader); ClassLoader getBeanClassLoader(); /* * 設置、返回一個臨時的類加載器 */ void setTempClassLoader(ClassLoader tempClassLoader); ClassLoader getTempClassLoader(); /* * 設置、是否緩存元數據,若是false,那麼每次請求實例,都會從類加載器從新加載(熱加載) */ void setCacheBeanMetadata(boolean cacheBeanMetadata); boolean isCacheBeanMetadata();//是否緩存元數據 /* * Bean表達式分解器 */ void setBeanExpressionResolver(BeanExpressionResolver resolver); BeanExpressionResolver getBeanExpressionResolver(); /* * 設置、返回一個轉換服務 */ void setConversionService(ConversionService conversionService); ConversionService getConversionService(); /* * 設置屬性編輯登記員... */ void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar); /* * 註冊經常使用屬性編輯器 */ void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass); /* * 用工廠中註冊的通用的編輯器初始化指定的屬性編輯註冊器 */ void copyRegisteredEditorsTo(PropertyEditorRegistry registry); /* * 設置、獲得一個類型轉換器 */ void setTypeConverter(TypeConverter typeConverter); TypeConverter getTypeConverter(); /* * 增長一個嵌入式的StringValueResolver */ void addEmbeddedValueResolver(StringValueResolver valueResolver); String resolveEmbeddedValue(String value);//分解指定的嵌入式的值 void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);//設置一個Bean後處理器 int getBeanPostProcessorCount();//返回Bean後處理器的數量 void registerScope(String scopeName, Scope scope);//註冊範圍 String[] getRegisteredScopeNames();//返回註冊的範圍名 Scope getRegisteredScope(String scopeName);//返回指定的範圍 AccessControlContext getAccessControlContext();//返回本工廠的一個安全訪問上下文 void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);//從其餘的工廠複製相關的全部配置 /* * 給指定的Bean註冊別名 */ void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException; void resolveAliases(StringValueResolver valueResolver);//根據指定的StringValueResolver移除全部的別名 /* * 返回指定Bean合併後的Bean定義 */ BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;//判斷指定Bean是否爲一個工廠Bean void setCurrentlyInCreation(String beanName, boolean inCreation);//設置一個Bean是否正在建立 boolean isCurrentlyInCreation(String beanName);//返回指定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(); //銷燬全部的單例類 }
在具體介紹以前,先看一下接口SingletonBeanRegistry的源碼:
public interface SingletonBeanRegistry { void registerSingleton(String beanName, Object singletonObject); //在容器內註冊一個單例類 Object getSingleton(String beanName);//返回給定名稱對應的單例類 boolean containsSingleton(String beanName);//給定名稱是否對應單例類 String[] getSingletonNames();//返回容器內全部單例類的名字 int getSingletonCount();//返回容器內註冊的單例類數量 }
能夠看到,SingletonBeanRegistry這個接口很是簡單,5個方法,實現了單例類註冊的功能。
ConfigurableBeanFactory同時繼承了HierarchicalBeanFactory 和 SingletonBeanRegistry 這兩個接口,即同時繼承了分層和單例類註冊的功能。
具體:
一、2個靜態不可變常量分別表明單例類和原型類。
二、1個設置父工廠的方法,跟HierarchicalBeanFactory接口的getParentBeanFactory方法互補。
三、4個跟類加載器有關的方法:get/set工廠類加載器和get/set臨時類加載器。
四、2個設置、是否緩存元數據的方法(熱加載開關)。
五、11個處理Bean註冊、加載等細節的方法,包括:Bean表達式分解器、轉換服務、屬性編輯登記員、屬性編輯器、屬性編輯註冊器、類型轉換器、嵌入式的字符串分解器
六、2個處理Bean後處理器的方法。
七、3個跟註冊範圍相關的方法。
八、1個返回安全訪問上下文的方法、1個從其餘的工廠複製相關的全部配置的方法。
九、2個跟Bean別名相關的方法、1個返回合併後的Bean定義的方法。
十、1個判斷是否爲工廠Bean的方法、2個跟當前Bean建立時機相關的方法。
十一、3個跟Bean依賴相關的方法、3個銷燬Bean相關的方法。
總結:這個巨大的工廠接口,繼承自HierarchicalBeanFactory 和 SingletonBeanRegistry 這兩個接口,並額外獨有37個方法!!!(看的我都快瘋了...)這37個方法包含了工廠建立、註冊一個Bean的衆多細節。這個工廠名爲ConfigurableBeanFactory,真是名不虛傳!統計一下此時的ConfigurableBeanFactory的方法數吧。自有的37個方法、HierarchicalBeanFactory的2個方法、SingletonBeanRegistry的5個方法、爺爺接口BeanFactory的10個方法,共有54個方法!雖然方法繁多,還算層次分明!
七、BeanFactory的集大成者——ConfigurableListableBeanFactory
源碼:
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory { void ignoreDependencyType(Class<?> type);//忽略自動裝配的依賴類型 void ignoreDependencyInterface(Class<?> ifc);//忽略自動裝配的接口 /* * 註冊一個可分解的依賴 */ void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue); /* * 判斷指定的Bean是否有資格做爲自動裝配的候選者 */ boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException; /* * 返回註冊的Bean定義 */ BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; void freezeConfiguration();//暫時凍結全部的Bean配置 boolean isConfigurationFrozen();//判斷本工廠配置是否被凍結 void preInstantiateSingletons() throws BeansException;//使全部的非延遲加載的單例類都實例化。 }
具體:
一、2個忽略自動裝配的的方法。
二、1個註冊一個可分解依賴的方法。
三、1個判斷指定的Bean是否有資格做爲自動裝配的候選者的方法。
四、1個根據指定bean名,返回註冊的Bean定義的方法。
五、2個凍結全部的Bean配置相關的方法。
六、1個使全部的非延遲加載的單例類都實例化的方法。
總結:工廠接口ConfigurableListableBeanFactory同時繼承了3個接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,擴展以後,加上自有的這8個方法,這個工廠接口總共有83個方法,實在是巨大到不行了。這個工廠接口的自有方法整體上只是對父類接口功能的補充,包含了BeanFactory體系目前的全部方法,能夠說是接口的集大成者。
八、額外的接口——BeanDefinitionRegistry
這個接口基本用來操做定義在工廠內部的BeanDefinition的。咱們先來看一下這個接口的父接口:
public interface AliasRegistry { void registerAlias(String name, String alias);//對指定的名稱註冊別名 void removeAlias(String alias);//從當前容器移除指定別名 boolean isAlias(String beanName);//判斷指定名稱是否爲別名 String[] getAliases(String name);//返回指定名稱的全部別名 }
能夠看到這4個方法都很是簡單,都是用來操道別名的。
再來看一下BeanDefinitionRegistry的源碼:
public interface BeanDefinitionRegistry extends AliasRegistry { void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;//給定bean名稱,註冊一個新的bean定義 /* * 根據指定Bean名移除對應的Bean定義 */ void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; /* * 根據指定bean名獲得對應的Bean定義 */ BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; /* * 查找,指定的Bean名是否包含Bean定義 */ boolean containsBeanDefinition(String beanName); String[] getBeanDefinitionNames();//返回本容器內全部註冊的Bean定義名稱 int getBeanDefinitionCount();//返回本容器內註冊的Bean定義數目 boolean isBeanNameInUse(String beanName);//指定Bean名是否被註冊過。 }
這7個方法都是用來操做容器內的BeanDefinition的。
下一結就會介紹BeanFactory體系的終極實現類——XmlBeanFactory