1. 程式人生 > >spring的BeanFactory和ApplicationContext原始碼詳解(一)

spring的BeanFactory和ApplicationContext原始碼詳解(一)

轉自http://www.sandzhang.com/blog/2011/04/10/Spring-BeanFactory-ApplicationContext-Detail-1/

版本:spring-framework-3.0.5.RELEASE

Spring的最核心的部分就是BeanFactory了,當然我們現在很少直接使用這個類而是通過ApplicationContext來使用了,本篇我們就對BeanFactory介面的核心方法、BeanFactory的子介面及其實現類以及ApplicationContext相關做一個詳細的分析和了解。關於實現程式碼牽扯到的東西太多了,這裡只分析介面的功能及繼承關係,暫時不做實現類的分析。

一、我們首先看下BeanFactory介面的程式碼:


[java] view plaincopyprint?
  1. publicinterface BeanFactory {  
  2.     String FACTORY_BEAN_PREFIX = "&";  
  3.     Object getBean(String name) throws BeansException;  
  4.     <T> T getBean(String name, Class<T> requiredType) throws BeansException;  
  5.     <T> T getBean(Class<T> requiredType) 
    throws BeansException;  
  6.     Object getBean(String name, Object... args) throws BeansException;  
  7. boolean containsBean(String name);  
  8. boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  
  9. boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  
  10. boolean isTypeMatch(String name, Class targetType) 
    throws NoSuchBeanDefinitionException;  
  11.     Class<?> getType(String name) throws NoSuchBeanDefinitionException;  
  12.     String[] getAliases(String name);  
  13. }  
public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";
 
    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);
}

  1. 首先第2行是一個字串常量,值為"&",這個是用在FactoryBean那部分,假如有一個FactoryBean的name=foo,則使用name=&foo去取bean物件的時候取到的就是foo的工廠而不是foo本身。
  2. 第4行根據bean的name去查詢bean,在當前BeanFactory查詢不到的時候會去查詢parent的BeanFactory,返回為一個Object物件需使用者自行轉換其原本的型別。
  3. 第5行也是根據name查詢bean,但是多了一個引數requiredType,查詢bean並要求結果符合這個型別,如果requiredType為null,則同上個方法一樣只根據name查詢,另外這裡使用了泛型,返回物件型別會直接是requiredType。
  4. 第6行是根據requiredType查詢bean,查詢一個符合這個型別的bean,同樣返回型別為requiredType。
  5. 第7行根據name查詢bean,同時有一個引數組args,這個主要是用來給給工廠類建立bean物件的時候呼叫的,所以如果args不為空則意味著這裡查詢的是一個prototype的bean。
  6. 第9-12行分別是幾個判斷方法:判斷是否存在bean;是否是單例bean;是否是prototype的bean,bean是否符合型別requiredType。
  7. 第13行是根據bean的name獲取bean的型別。
  8. 最後是根據bean的name獲取指向該bean的所有別名,如果輸入的name本身就是別名,那返回的將包括bean的最初name,並且這個name在返回的陣列中第一個元素。
     

二、現在我們看下BeanFactory的子介面

BeanFactory一共有3個子介面一個實現類,其中實現類SimpleJndiBeanFactory主要是jndi相關,我們這裡暫不討論,下面看3個介面

2.1、HierarchicalBeanFactory介面:主要定義BeanFactory的分層的支撐,所謂分層也就是parentBeanFactory概念

2.1.1、首先看下程式碼:

[java] view plaincopyprint?
  1. publicinterface HierarchicalBeanFactory extends BeanFactory {  
  2.     BeanFactory getParentBeanFactory();  
  3. boolean containsLocalBean(String name);  
  4. }  
public interface HierarchicalBeanFactory extends BeanFactory {
    BeanFactory getParentBeanFactory();
    boolean containsLocalBean(String name);
}

  1. getParentBeanFactory()方法獲取parentBeanFactory;
  2. containsLocalBean()則類似containsBean()只不過這個方法只在當前BeanFactory查詢bean,如果沒有不再去parent裡查找了。
     

2.1.2、這個介面有兩個子介面:ApplicationContext和ConfigurableBeanFactory,關於這兩個子介面下面獨立做分析,因為他們已經不只是HierarchicalBeanFactory的子介面了。

2.2、ListableBeanFactory介面:主要是獲取bean的定義和配置資訊相關的支撐介面

2.2.1、程式碼如下:

[java] view plaincopyprint?
  1. publicinterface ListableBeanFactory extends BeanFactory {  
  2. boolean containsBeanDefinition(String beanName);  
  3. int getBeanDefinitionCount();  
  4.     String[] getBeanDefinitionNames();  
  5.     String[] getBeanNamesForType(Class type);  
  6.     String[] getBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit);  
  7.     <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;  
  8.     <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)  
  9. throws BeansException;  
  10.     Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)  
  11. throws BeansException;  
  12.     <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);  
  13. }  
public interface ListableBeanFactory extends BeanFactory {
    boolean containsBeanDefinition(String beanName);
    int getBeanDefinitionCount();
    String[] getBeanDefinitionNames();
    String[] getBeanNamesForType(Class type);
    String[] getBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit);
    <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
    <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
            throws BeansException;
    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
            throws BeansException;
    <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
}

  • containsBeanDefinition()方法判斷是否存在指定beanName的定義資訊
  • getBeanDefinitionCount()獲取bean定義的總數
  • getBeanDefinitionNames()獲取所有bean定義的name陣列
  • getBeanNamesForType()獲取所有指定型別的bean的name陣列
  • 第2個getBeanNamesForType()方法多了兩個餐廚,可以指定是否單例,是否渴望初始化
  • 兩個getBeansOfType()和getBeanNamesForType()的引數一樣,只不過這個返回的是name為key,bean物件為value的map集合
  • getBeansWithAnnotation()方法獲取包含指定註解annotationType所有bean的map集合
  • 最後findAnnotationOnBean()方法獲取指定beanName的指定註解的註解資訊物件
     

2.1.2、這個介面有兩個子介面:ApplicationContext和ConfigurableListableBeanFactory,關於這兩個子介面同樣放到下面獨立做分析。

注:該介面還有一個靜態實現類StaticListableBeanFactory,沒發現哪裡在使用,程式碼上也很簡單就是把bean的定義放到一個map集合beans裡面,實現一個基本的本介面功能,暫不做分析。
 

2.3、AutowireCapableBeanFactory介面:主要是spring的自動裝配相關功能支撐介面

2.3.1、程式碼如下:

[java] view plaincopyprint?
  1. publicinterface AutowireCapableBeanFactory extends BeanFactory {  
  2. int AUTOWIRE_NO = 0;  
  3. int AUTOWIRE_BY_NAME = 1;  
  4. int AUTOWIRE_BY_TYPE = 2;  
  5. int AUTOWIRE_CONSTRUCTOR = 3;  
  6. int AUTOWIRE_AUTODETECT = 4;  
  7.     <T> T createBean(Class<T> beanClass) throws BeansException;  
  8.     Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;  
  9.     Object configureBean(Object existingBean, String beanName) throws BeansException;  
  10.     Object initializeBean(Object existingBean, String beanName) throws BeansException;  
  11.     Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;  
  12. void autowireBean(Object existingBean) throws BeansException;  
  13. void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)  
  14. throws BeansException;  
  15. void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;  
  16.     Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)  
  17. throws BeansException;  
  18.     Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)  
  19. throws BeansException;  
  20.     Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException;  
  21.     Object resolveDependency(DependencyDescriptor descriptor, String beanName,  
  22.             Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;  
  23. }  
public interface AutowireCapableBeanFactory extends BeanFactory {
    int AUTOWIRE_NO = 0;
    int AUTOWIRE_BY_NAME = 1;
    int AUTOWIRE_BY_TYPE = 2;
    int AUTOWIRE_CONSTRUCTOR = 3;
    int AUTOWIRE_AUTODETECT = 4;
 
    <T> T createBean(Class<T> beanClass) throws BeansException;
    Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
 
    Object configureBean(Object existingBean, String beanName) throws BeansException;
    Object initializeBean(Object existingBean, String beanName) throws BeansException;
    Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
    void autowireBean(Object existingBean) throws BeansException;
    void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
            throws BeansException;
    void applyBeanPropertyValues(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) throws BeansException;
    Object resolveDependency(DependencyDescriptor descriptor, String beanName,
            Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
}

這個介面的主要實現程式碼都在AbstractAutowireCapableBeanFactory類中,暫時也沒有發現其他地方用到這個介面,檢視這些方法的實現可以去看這個類。

  • 首先是5個常量代表自動裝配的型別:不自動裝配、按name、按型別、根據自省完全自動裝配(不推薦,已在3.0中過時)。
  • 兩個建立Bean的方法,一個是根據型別,另外一個多了兩個引數自動裝配型別和是否檢查依賴
  • configureBean()是一個用來主動的配置裝配的,就是在需要的時候把existingBean自動裝配給beanName對應的bean
  • initializeBean()是bean的初始化方法在這裡主要呼叫了幾個工廠級回撥(BeanNameAware、BeanClassLoaderAware和BeanFactoryAware),並處理了所有BeanPostProcessor的兩個呼叫
  • autowire()方法建立一個型別為beanClass的bean物件,並根據自動裝配型別autowireMode進行自動裝配,dependencyCheck則代表是否做依賴檢查
  • autowireBean()方法暫時沒有很清楚,只知道和普通的按name按型別裝配不同,和註解相關,以後分析清楚了再補充。
  • autowireBeanProperties方法()和上面的方法類似,只不過省略了bean建立的步驟,直接穿入一個bean物件進行自動裝配
  • applyBeanPropertyValues()應用bean定義中明確定義的屬性值,區別於autowireBeanProperties(會裝配所有屬性)。
  • applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization()兩個方法處理BeanPostProcessor的兩種回撥,上面的initializeBean()方法的實現中就是呼叫這兩個
  • 兩個resolveDependency()方法也沒有搞清楚,是跟bean的依賴相關的,以後清楚了再補充。

2.3.2、這個介面的繼承結構也很清晰,一個子介面ConfigurableListableBeanFactory,一個實現類AbstractAutowireCapableBeanFactory。