BeanFactory是Spring IOC實現的基礎,這邊定義了一系列的介面,我們通過這些介面的學習,可以大致瞭解BeanFactory體系各介面如何分工合作.為閱讀具體實現打下基礎.
不知道為什麼看著Spring的源碼,感觸最深的是Spring對概念的抽象,所以我就先學介面了.
BeanFactory是Spring IOC實現的基礎,這邊定義了一系列的介面,我們通過這些介面的學習,可以大致瞭解BeanFactory體系各介面如何分工合作.
為學習具體實現打下基礎.畢竟這邊邏輯複雜,涉及的概念很多.
BeanFactory 是Spring bean容器的根介面.提供獲取bean,是否包含bean,是否單例與原型,獲取bean類型,bean 別名的api.
-- AutowireCapableBeanFactory 添加集成其他框架功能.如果集成WebWork則可以使用Spring對Actions等進行管理.
-- HierarchicalBeanFactory 提供父容器的訪問功能
-- -- ConfigurableBeanFactory 如名,提供factory的配置功能,眼花繚亂好多api
-- -- -- ConfigurableListableBeanFactory 集大成者,提供解析,修改bean定義,並與初始化單例.
-- ListableBeanFactory 提供容器內bean實例的枚舉功能.這邊不會考慮父容器內的實例.
看到這邊,我們是不是想起了設計模式原則里的介面隔離原則
Interface Segregation Principle(ISP):客戶端不應該依賴它不需要的介面;類間的依賴關係應該建立在最小的介面上
對這個有興趣的話,找度娘或者看看這個設計模式六大原則(4):介面隔離原則
這邊清晰地定義瞭如下的體系:
根介面BeanFactory(基礎容器)
第二層: 第三方集成,繼承體系,遍歷bean
第三層: 配置功能
第四層: 配置+迭代
接下來具體分析下各個介面吧(順便做目錄):
1. BeanFactory
2. AutowireCapableBeanFactory
3. HierarchicalBeanFactory
4. ListableBeanFactory
5. ConfigurableBeanFactory
6. ConfigableListableBeanFactory
1. BeanFactory
BeanFactory是Spring bean容器的根介面.
每個bean都是通過string類型bean name進行標識.這邊提供了設計模式單例,原型的替代實現.
如果bean name配置為單例,應用內只會獲取到一個實例.如果配置為原型,那麼可以實例化好後填充屬性(基於用戶的配置).
BeanFactory作為應用集中配置管理的地方,極大簡便應用開發,這樣開發人員可以集中與業務.
BeanFactory需要管理bean的生命周期,比如初始化時需要按順序實現如下介面:
1. BeanNameAware's {@code setBeanName}
2. BeanClassLoaderAware's {@code setBeanClassLoader}
3. BeanFactoryAware's {@code setBeanFactory}
4. ResourceLoaderAware's {@code setResourceLoader}僅對application context有效
5. ApplicationEventPublisherAware's {@code setApplicationEventPublisher}僅對application context有效
6. MessageSourceAware's {@code setMessageSource}僅對application context有效
7. ApplicationContextAware's {@code setApplicationContext}僅對application context有效
8. ServletContextAware's {@code setServletContext}僅對application context有效
9. {@code postProcessBeforeInitialization} methods of BeanPostProcessors
10. InitializingBean's {@code afterPropertiesSet}
11. a custom init-method definition xml中配置的init-method
12. {@code postProcessAfterInitialization} methods of BeanPostProcessors
還有關閉容器的介面:
1. DisposableBean's {@code destroy}
2. a custom destroy-method definition xml配置中的destroy-method
介面里定義了一個變數String FACTORY_BEAN_PREFIX = "&";
這是用來區分是獲取FactoryBean還是FactoryBean的createBean創建的實例.如果&開始則獲取FactoryBean;否則獲取createBean創建的實例.
我們來看下定義的方法:
a, 獲取bean,這邊可以實現單例,原型
Object getBean(String name) throws BeansException; 可以用別名查找哦
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException; 這邊的類型可以是介面或者子類,但不能是null
Object getBean(String name, Object... args) throws BeansException;
b, 判斷是否包含bean.陷阱出現:這邊不管類是否抽象類,懶載入,是否在容器範圍內,只要符合都返回true,所以這邊true,不一定能從getBean獲取實例
boolean containsBean(String name);
c, 單例,原型,bean類型的判斷
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
d, 獲取bean 的類型,別名
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
2. AutowireCapableBeanFactory
在BeanFactory基礎上實現對已存在實例的管理.
可以使用這個介面集成其它框架,捆綁並填充並不由Spring管理生命周期並已存在的實例.像集成WebWork的Actions 和Tapestry Page就很實用.
一般應用開發者不會使用這個介面,所以像ApplicationContext這樣的外觀實現類不會實現這個介面,如果真手癢癢可以通過ApplicationContext的getAutowireCapableBeanFactory介面獲取.
這邊定義了5種自動裝配策略:不註入AUTOWIRE_NO,使用bean name策略裝配AUTOWIRE_BY_NAME,使用類型裝配策略AUTOWIRE_BY_TYPE,使用構造器裝配策略AUTOWIRE_CONSTRUCTOR,自動裝配策略AUTOWIRE_AUTODETECT
這邊的自動策略是先嘗試構造器,然後才是byType.這邊應該是跟xml配置文件中的裝配策略對應.
繼續看定義的api:
a, 創建和填充外部bean實例的典型方法
<T> T createBean(Class<T> beanClass) throws BeansException;
void autowireBean(Object existingBean) throws BeansException; // 使用autowireBeanProperties裝配屬性
Object configureBean(Object existingBean, String beanName) throws BeansException; // 自動裝配屬性,填充屬性值,使用諸如setBeanName,setBeanFactory這樣的工廠回調填充屬性,最好還要調用post processor
Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException;
b, 在bean的生命周期進行細粒度控制的專門方法
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException; // 會執行bean完整的初始化,包括BeanPostProcessors和initializeBean
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;
Object initializeBean(Object existingBean, String beanName) throws BeansException;
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException;
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException;
Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
3. HierarchicalBeanFactory
提供父容器的訪問功能.至於父容器的設置,需要找ConfigurableBeanFactory的setParentBeanFactory(介面把設置跟獲取給拆開了!).
這邊可說的不多,直接上api:
a, 獲取父容器 bean factory
BeanFactory getParentBeanFactory();
b, 判斷當前容器是否保護bean
boolean containsLocalBean(String name);
4. ListableBeanFactory
獲取bean時,Spring 鼓勵使用這個介面定義的api. 還有個Beanfactory方便使用.其他的4個介面都是不鼓勵使用的.
提供容器中bean迭代的功能,不再需要一個個bean地查找.比如可以一次獲取全部的bean(太暴力了),根據類型獲取bean.在看SpringMVC時,掃描包路徑下的具體實現策略就是使用的這種方式(那邊使用的是BeanFactoryUtils封裝的api).
如果同時實現了HierarchicalBeanFactory,返回值不會考慮父類BeanFactory,只考慮當前factory定義的類.當然也可以使用BeanFactoryUtils輔助類來查找祖先工廠中的類.
這個介面中的方法只會考慮本factory定義的bean.這些方法會忽略ConfigurableBeanFactory的registerSingleton註冊的單例bean(getBeanNamesOfType和getBeansOfType是例外,一樣會考慮手動註冊的單例).當然BeanFactory的getBean一樣可以透明訪問這些特殊bean.當然在典型情況下,所有的bean都是由external bean定義,所以應用不需要顧慮這些差別.
註意:getBeanDefinitionCount和containsBeanDefinition的實現方法因為效率比較低,還是少用為好.
繼續上api吧
a, 暴力獲取全部bean的屬性:
boolean containsBeanDefinition(String beanName); //是否包含bean
int getBeanDefinitionCount(); // 當前factory中定義的bean數量
String[] getBeanDefinitionNames(); // 獲取當前工廠中定義的所有bean 的name
b, 根據bean 的類型獲取bean
這邊的方法僅檢查頂級bean.它不會檢查嵌套的bean.FactoryBean創建的bean會匹配為FactoryBean而不是原始類型.
一樣不會考慮父factory中的bean,非要用可以通過BeanFactoryUtils中的beanNamesForTypeIncludingAncestors.
其他方式註冊的單例這邊會納入判斷.
這個版本的getBeanNamesForType會匹配所有類型的bean,包括單例,原型,FactoryBean.返回的bean names會根據backend 配置的進行排序.
String[] getBeanNamesForType(Class<?> type); // 獲取給定類型的bean names(包括子類),通過bean 定義或者FactoryBean的getObjectType判斷.
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; // 如果保護懶載入的類,FactoryBean初始化的類和工廠方法初始化的類會被初始化.就是說執行這個方法會執行對應的初始化.
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;
c, 查找使用註解的類
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
d, 查找一個類上的註解,如果找不到,父類,介面使用註解也算.
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
5. ConfigurableBeanFactory
定義BeanFactory的配置.
這邊定義了太多太多的api,比如類載入器,類型轉化,屬性編輯器,BeanPostProcessor,作用域,bean定義,處理bean依賴關係,合併其他ConfigurableBeanFactory,bean如何銷毀.
定義了兩個作用域: 單例和原型.可以通過registerScope來添加.
SCOPE_SINGLETON,SCOPE_PROTOTYPE
這邊定義了好多好多的api,所以我們這邊只講業務,具體的api看文末的附錄吧:
a, 父容器設置.而且一旦設置了就不讓修改
b, 類載入器設置與獲取.預設使用當前線程中的類載入器
c, 為了類型匹配,搞個臨時類載入器.好在一般情況為null,使用上面定義的標準載入器
d, 是否需要緩存bean metadata,比如bean difinition 和 解析好的classes.預設開啟緩存
e, 定義用於解析bean definition的表達式解析器
f, 類型轉化器
g, 屬性編輯器
h, BeanFactory用來轉換bean屬性值或者參數值的自定義轉換器
i,string值解析器(想起mvc中的ArgumentResolver了)
j,大boss BeanPostProcessor用於增強bean初始化功能
k,作用域定義
l,訪問許可權控制
m, 合併其他ConfigurableBeanFactory的配置,包括上面說到的BeanPostProcessor,作用域等
n, bean定義處理
o, bean創建狀態控制.在解決迴圈依賴時有使用
p, 處理bean依賴問題
q, bean生命周期管理-- 銷毀bean
6. ConfigableListableBeanFactory
提供bean definition的解析,註冊功能,再對單例來個預載入(解決迴圈依賴問題).
貌似我們一般開發就會直接定義這麼個介面了事.而不是像Spring這樣先根據使用情況細分那麼多,到這邊再合併
a, 設置忽略的依賴關係,註冊找到的特殊依賴
void ignoreDependencyType(Class<?> type); // 忽略類型
void ignoreDependencyInterface(Class<?> ifc); // 忽略介面
void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException;
b, 獲取bean定義 (可以訪問屬性值跟構造方法的參數值)
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
c, 鎖定配置信息.在調用refresh時會使用到.
void freezeConfiguration();
boolean isConfigurationFrozen();
d, 預載入不是懶載入的單例.用於解決迴圈依賴問題
void preInstantiateSingletons() throws BeansException;
附錄--ConfigureableBeanFactory中定義的api:
a, 父容器設置.而且一旦設置了就不讓修改
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
b, 類載入器設置與獲取.預設使用當前線程中的類載入器
void setBeanClassLoader(ClassLoader beanClassLoader);
ClassLoader getBeanClassLoader();
c, 為了類型匹配,搞個臨時類載入器.好在一般情況為null,使用上面定義的標準載入器
void setTempClassLoader(ClassLoader tempClassLoader);
ClassLoader getTempClassLoader();
d, 是否需要緩存bean metadata,比如bean difinition 和 解析好的classes.預設開啟緩存
void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata();
e, 定義用於解析bean definition的表達式解析器
void setBeanExpressionResolver(BeanExpressionResolver resolver);
BeanExpressionResolver getBeanExpressionResolver();
f, 類型轉化器
void setConversionService(ConversionService conversionService);
ConversionService getConversionService();
g, 屬性編輯器
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
h, BeanFactory用來轉換bean屬性值或者參數值的自定義轉換器
void setTypeConverter(TypeConverter typeConverter);
TypeConverter getTypeConverter();
i,string值解析器(想起mvc中的ArgumentResolver了)
void addEmbeddedValueResolver(StringValueResolver valueResolver);
String resolveEmbeddedValue(String value);
j,大boss BeanPostProcessor用於增強bean初始化功能
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
int getBeanPostProcessorCount();
k,作用域定義
void registerScope(String scopeName, Scope scope);
String[] getRegisteredScopeNames();
Scope getRegisteredScope(String scopeName);
l,訪問許可權控制
AccessControlContext getAccessControlContext();
m, 合併其他ConfigurableBeanFactory的配置,包括上面說到的BeanPostProcessor,作用域等
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
n, bean定義處理
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException; // 註冊別名
void resolveAliases(StringValueResolver valueResolver);
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 合併bean定義,包括父容器的
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException; // 是否是FactoryBean類型
o, bean創建狀態控制.在解決迴圈依賴時有使用
void setCurrentlyInCreation(String beanName, boolean inCreation);
boolean isCurrentlyInCreation(String beanName);
p, 處理bean依賴問題
void registerDependentBean(String beanName, String dependentBeanName);
String[] getDependentBeans(String beanName);
String[] getDependenciesForBean(String beanName);
q, bean生命周期管理-- 銷毀bean
void destroyBean(String beanName, Object beanInstance);
void destroyScopedBean(String beanName);
void destroySingletons();