Spring MVC 解讀——@Autowired、@Controller、@Service從原理層面來分析


目錄(?)[+]

  1. Spring MVC 解讀Autowired
    1. 一Autowired
    2. 二BeanPostProcessor
    3. 三磨刀砍柴    
    4. 四Bean 工廠
    5. 五實例化與裝配
    6. 六執行裝配
    7. 七一切的開始
 

Spring MVC 解讀——@Autowired

一、@Autowired

    作為一個spring開發者對@Autowired注解必定是非常了解了, 顧名思義自動裝配,應該是Spring會自動將我們標記為@Autowired的元素裝配好,與其猜測不如看看它的定義:

 
  1. @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD,  
  2.                          ElementType.ANNOTATION_TYPE})  
  3. @Retention(RetentionPolicy.RUNTIME)  
  4. @Documented  
  5. public @interface Autowired {  
  6.     boolean required() default true;  
  7. }  
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD,
                         ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
}
 

 很明顯這個注解可以用到構造器,變量域,方法,注解類型上。文檔上這樣描述:將一個構造器,變量域,setter方法,config方法標記為被Spring DI 工具自動裝配。換句話說,我們視圖從bean 工廠中獲取一個bean時,Spring會自動為我們裝配該bean中標記為@Autowired的元素,而無需我們手動完成。這些相信大家都明白,但問題是,Spring是怎樣做到的?在Spring MVC中怎樣做到的?什么時候進行的自動裝配?下面我們就來探究下這些問題。

二、BeanPostProcessor

    在@Autowired的定義中有下面一段話:

  1. <pre name="code" class="java">Note that actual injection is performed through a BeanPostProcessor   
  2. which in turn means that you cannot use @Autowired to inject references into BeanPostProcessor  
  3. or BeanFactoryPostProcessor types.   
  4. Please consult the javadoc for the AutowiredAnnotationBeanPostProcessor class   
  5. (which, by default, checks for the presence of this annotation).  
<pre name="code" class="java">Note that actual injection is performed through a BeanPostProcessor 
which in turn means that you cannot use @Autowired to inject references into BeanPostProcessor
or BeanFactoryPostProcessor types. 
Please consult the javadoc for the AutowiredAnnotationBeanPostProcessor class 
(which, by default, checks for the presence of this annotation).
 

意思是:實際的注入裝配動作是由BeanPostProcessor執行的,翻過來說你不能將@Autowired注解用於BeanPostProcessor或BeanFactoryPostProcessor類型上。請查看AutowiredAnnotationBeanPostProcessor文檔(默認情況下,被用來檢查@Autowired注解)。

    文檔說的很清楚了,BeanPostProcessor來執行自動裝配,並且默認情況下使用AutowiredAnnotationBeanPostProcessor實現類完成。那我們不妨看一下他們的定義:

?
 
 
  1. public interface BeanPostProcessor {  
  2.     Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;  
  3.     Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;  
  4. }  
public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
 

   BeanPostProcessor就一個回調接口,定義了兩個方法聲明,一個是實例化前被調用,一個是實例化后被調用,沒啥好看的,我們直接看看它的實現類AutowiredAnnotationBeanPostProcessor:

 
 
  1. BeanPostProcessor implementation that autowires annotated fields, setter methods and arbitrary   
  2. config methods. Such members to be injected are detected through a Java 5 annotation:   
  3. by default, Spring's @Autowired and @Value annotations.Also supports JSR-330's @Inject   
  4. annotation, if available, as a direct alternative to Spring's own @Autowired.  
  5.    
  6. Note: A default AutowiredAnnotationBeanPostProcessor will be registered by   
  7. the "context:annotation-config" and "context:component-scan" XML tags.  
  8.    
  9. NOTE: Annotation injection will be performed before XML   
  10. injection; thus the latter configuration will override the former for properties   
  11. wired through both approaches.  
BeanPostProcessor implementation that autowires annotated fields, setter methods and arbitrary 
config methods. Such members to be injected are detected through a Java 5 annotation: 
by default, Spring's @Autowired and @Value annotations.Also supports JSR-330's @Inject 
annotation, if available, as a direct alternative to Spring's own @Autowired.
 
Note: A default AutowiredAnnotationBeanPostProcessor will be registered by 
the "context:annotation-config" and "context:component-scan" XML tags.
 
NOTE: Annotation injection will be performed before XML 
injection; thus the latter configuration will override the former for properties 
wired through both approaches.

   上面是AutowiredAnnotationBeanPostProcessor類的描述文檔摘要,大致意思是:這是BeanPostProcessor接口的一個實現,用來自動裝配注解的變量域,setter方法和任意的config方法。這些被注入的元素是通過檢測Java 5的注解完成的:默認情況下是@Autowired和@Value注解。同樣也支持JSR-330的@Inject注解。並且,<context:annotation-config/>和<context:component-scan/>XML標簽可以默認注冊AutowiredAnnotationBeanPostProcessor到bean工廠中。最后,注解注入會在XML注入之前執行;因此后面的配置會覆蓋前面已經裝配好的元素。

    是不是很清楚了?Spring的文檔總是這么詳細,要么說是教科書呢,廢話不多說,我們才剛進正題呢,既然我們清楚了是AutowiredAnnotationBeanPostProcessor實例執行了自動裝配,那么它做了什么呢?

三、磨刀砍柴   

在正式查看源碼前,我先大致的講一下整個裝配的過程,以便后面理解起來輕松些。其實整體思路還是很簡單的,我們舉個簡單的例子:

 
  1. //==================================Controller  
  2. @Controller  
  3. public class SimpleController {  
  4.     @Autowired  
  5.     private SimpleService simpleService;  
  6. }  
  7. //==================================Service  
  8. @Service("simpleService")  
  9. public class SimpleServiceImpl implements SimpleService {  
  10.     @Autowired  
  11.     private SimpleDao simpleDao;  
  12. }  
  13. //===================================Repository  
  14. @Repository("simpleDao")  
  15. public class SimpleDaoImpl implements SimpleDao {  
  16. }  
//==================================Controller
@Controller
public class SimpleController {
    @Autowired
    private SimpleService simpleService;
}
//==================================Service
@Service("simpleService")
public class SimpleServiceImpl implements SimpleService {
    @Autowired
    private SimpleDao simpleDao;
}
//===================================Repository
@Repository("simpleDao")
public class SimpleDaoImpl implements SimpleDao {
}
 

1)在某一時刻Spring調用了 Bean工廠 的 getBean(beanName) 方法。beanName可能是simpleController,或者simpleService,simpleDao,順序沒關系(因為后面會有依賴關系的處理)。我們假設simpleController吧。

2)getBean方法首先會調用Bean工廠中定義的getSingleton(beanName)方法,來判斷是否存在該名字的bean單例,若果存在則返回,方法調用結束。

3)否則,Spring會檢查是否存在父工廠,如果有則返回,方法調用結束。

4)否則,Spring 會檢查該bean 定義(BeanDefinition實例,用來描述Bean結構,上篇文章講到過,component-scan 掃描后,就是將beanDefinition實例放入Bean工廠,此時Bean還沒有被實例化。)是否有依賴關系,如果有,執行1)步,獲取依賴的bean實例。

5)否則,Spring會嘗試創建這個bean實例,創建實例前,Spring會檢查確定調用的構造器,並實例化該Bean。

6)實例化完成后,Spring會調用Bean工廠的populateBean方法來填充bean實例的屬性,也就是我們前面提到的自動轉配了。populateBean方法便是調用了BeanPostProcessor實例來完成屬性元素的自動裝配工作。

7)在元素裝配過程中,Spring會檢查被裝配的屬性是否存在自動裝配的其他屬性,然后遞歸調用getBean方法,直到所有@Autowired的元素都被裝配完成。如在裝配simpleController中的simpleService屬性時,發現SimpleServiceImpl實例中存在@Autowired屬性simpleDao,然后調用getBean(simpleDao)方法,同樣會執行1)-7)整個過程。所以可以看成一個遞歸過程。

8)裝配完成后,Bean工廠會將所有的bean實例都添加到工廠中來。

注:我們知道Spring MVC是多線程單實例的MVC框架,就是說,對於同一個Controller,只會生成一個實例來處理所有的請求,因此bean實例只會實例化一次,並被存放在工廠中,以供其他請求使用。

好了,大致了解整個流程后我們看一下Spring的具體行為吧。

四、Bean 工廠

    前面多次提到了Bean工廠,但一直沒有說它到底是個什么,這里我們就徹底弄清楚吧,省的雲里霧里,這樣我們后面講到Bean工廠就不會暈了。看過上一篇博客(<context:component-scan/>)的朋友可能記得DefaultListableBeanFactory這個類,當時是它保存了掃描到的組件--Bean Definition實例。那他是否是我們所說的Bean工廠呢?是否保存了Bean實例呢?答案是:對。

我們可以看到DefaultLiableBeanFactory繼承自DefaultSingletonBeanRegistry,AbstractBeanFactory,AbstractAutowireCapableBeanFactory。下面就列出了一下相關的Bean工廠中的屬性和方法:

 
  1. //==========================================================================================  
  2. //==============================DefaultListableBeanFactory================================  
  3. //==========================================================================================  
  4. //beanName-beanDefinition 的映射表  
  5. private final Map<String, BeanDefinition> beanDefinitionMap =   
  6.                                             new ConcurrentHashMap<String, BeanDefinition>(64);  
  7. //beanName 列表  
  8. private final List<String> beanDefinitionNames = new ArrayList<String>();  
  9. //==========================================================================================  
  10. //=============================AbstractBeanFactory=================================  
  11. //==========================================================================================  
  12. //注冊了所有的BeanPostProcessor實例,包括前面提到的用來處理@Autowired注解的  
  13. //AutowiredAnnotationBeanPostProcessor   
  14. private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();  
  15. //可能存在的父親Bean工廠  
  16. private BeanFactory parentBeanFactory;  
  17. //==========================================================================================  
  18. //==============================DefaultSingletonBeanRegistry================================  
  19. //==========================================================================================  
  20. //beanName--bean單例的映射表  
  21. private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);  
  22. //注冊過的beanName集合  
  23. private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);  
  24. //beanName與該bean所依賴的Beans集合的映射表,如simpleDao依賴與simpleService,如果還有其他  
  25. service使用該Dao,如simpleService2那么是simpleDao->[simpleService,simpleService2]  
  26. private final Map<String, Set<String>> dependentBeanMap   
  27.                                             = new ConcurrentHashMap<String, Set<String>>(64);  
  28. //恰好與上面相反,beanName與該bean所包含的beans的集合映射表,如simpleController->[simpleService]  
  29. private final Map<String, Set<String>> dependenciesForBeanMap   
  30.                                             = new ConcurrentHashMap<String, Set<String>>(64);  
//==========================================================================================
//==============================DefaultListableBeanFactory================================
//==========================================================================================
//beanName-beanDefinition 的映射表
private final Map<String, BeanDefinition> beanDefinitionMap = 
                                            new ConcurrentHashMap<String, BeanDefinition>(64);
//beanName 列表
private final List<String> beanDefinitionNames = new ArrayList<String>();
//==========================================================================================
//=============================AbstractBeanFactory=================================
//==========================================================================================
//注冊了所有的BeanPostProcessor實例,包括前面提到的用來處理@Autowired注解的
//AutowiredAnnotationBeanPostProcessor 
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
//可能存在的父親Bean工廠
private BeanFactory parentBeanFactory;
//==========================================================================================
//==============================DefaultSingletonBeanRegistry================================
//==========================================================================================
//beanName--bean單例的映射表
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
//注冊過的beanName集合
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
//beanName與該bean所依賴的Beans集合的映射表,如simpleDao依賴與simpleService,如果還有其他
service使用該Dao,如simpleService2那么是simpleDao->[simpleService,simpleService2]
private final Map<String, Set<String>> dependentBeanMap 
                                            = new ConcurrentHashMap<String, Set<String>>(64);
//恰好與上面相反,beanName與該bean所包含的beans的集合映射表,如simpleController->[simpleService]
private final Map<String, Set<String>> dependenciesForBeanMap 
                                            = new ConcurrentHashMap<String, Set<String>>(64);

   可以看到Bean工廠中即存有bean definition的映射表,也存有bean name的別表,以及bean實例的映射表,還有依賴關系圖。理解了這個對下面的實例化以及裝配過程會有很大幫助。

五,實例化與裝配

  下面我們就從頭到尾看一下整個的實例化和裝配過程:

 
  1. public Object getBean(String name) throws BeansException {  
  2.     return doGetBean(name, null, null, false);  
  3. }  
  4.    
  5. @SuppressWarnings("unchecked")  
  6. protected <T> T doGetBean(final String name, final Class<T> requiredType,   
  7.                           final Object[] args, boolean typeCheckOnly)throws BeansException {  
  8.         //去掉工廠bean的前綴或者將別名轉化為規范名  
  9.         final String beanName = transformedBeanName(name);  
  10.         Object bean;  
  11.         // 檢查是否有已經注冊的bean實例  
  12.         Object sharedInstance = getSingleton(beanName);  
  13.         if (sharedInstance != null && args == null) {  
  14.             //如果是工廠bean,獲取工廠bean創建的bean  
  15.             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
  16.         }  
  17.         else {  
  18.             //判斷是否有父工廠,並且其中是否存在該bean實例?  
  19.             BeanFactory parentBeanFactory = getParentBeanFactory();  
  20.             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {  
  21.                 String nameToLookup = originalBeanName(name);  
  22.                 if (args != null) {  
  23.                     return (T) parentBeanFactory.getBean(nameToLookup, args);  
  24.                 }  
  25.                 else {  
  26.                     return parentBeanFactory.getBean(nameToLookup, requiredType);  
  27.                 }  
  28.             }  
  29.             if (!typeCheckOnly) {  
  30.                 markBeanAsCreated(beanName);//將該beanName標記為已經實例化  
  31.             }  
  32.             //獲取該beanName對應的BeanDefinition實例,從上面說到的beanDefinitionMap表中查找  
  33.             final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  
  34.             checkMergedBeanDefinition(mbd, beanName, args);  
  35.             //判斷是否有依賴bean  
  36.             String[] dependsOn = mbd.getDependsOn();  
  37.             if (dependsOn != null) {  
  38.                 for (String dependsOnBean : dependsOn) {  
  39.                     getBean(dependsOnBean);//如果有依賴bean,遞歸調用getBean方法  
  40.                     registerDependentBean(dependsOnBean, beanName);//將依賴關系保存到 上面提到的  
  41.                     //dependBeanMap和dependencyForBeanMap中。  
  42.                 }  
  43.             }  
  44.             // 真正的開始床架bean實例了。激動吧  
  45.             if (mbd.isSingleton()) {//beanDefinition中指定該實例為單例  
  46.                 //去工廠中獲取單例,如果沒有創建一個,然后添加到工廠中,否則直接返回  
  47.                 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {  
  48.                     public Object getObject() throws BeansException {  
  49.                         try {  
  50.                             return createBean(beanName, mbd, args);  
  51.                         }  
  52.                     }  
  53.                 });  
  54.                 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
  55.             }  
  56.             else if (mbd.isPrototype()) {//原型方式,每次都創建一個新的實例  
  57.                 Object prototypeInstance = null;  
  58.                 try {  
  59.                     beforePrototypeCreation(beanName);  
  60.                     prototypeInstance = createBean(beanName, mbd, args);  
  61.                 }  
  62.                 finally {  
  63.                     afterPrototypeCreation(beanName);  
  64.                 }  
  65.                 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);  
  66.             }  
  67.             else {//其他方式,如目前主體無關,不贅述  
  68.             }  
  69.         }  
  70.         return (T) bean;  
  71.     }  
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}
 
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, final Class<T> requiredType, 
                          final Object[] args, boolean typeCheckOnly)throws BeansException {
        //去掉工廠bean的前綴或者將別名轉化為規范名
        final String beanName = transformedBeanName(name);
        Object bean;
        // 檢查是否有已經注冊的bean實例
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            //如果是工廠bean,獲取工廠bean創建的bean
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        else {
            //判斷是否有父工廠,並且其中是否存在該bean實例?
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                String nameToLookup = originalBeanName(name);
                if (args != null) {
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);//將該beanName標記為已經實例化
            }
            //獲取該beanName對應的BeanDefinition實例,從上面說到的beanDefinitionMap表中查找
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
            //判斷是否有依賴bean
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dependsOnBean : dependsOn) {
                    getBean(dependsOnBean);//如果有依賴bean,遞歸調用getBean方法
                    registerDependentBean(dependsOnBean, beanName);//將依賴關系保存到 上面提到的
                    //dependBeanMap和dependencyForBeanMap中。
                }
            }
            // 真正的開始床架bean實例了。激動吧
            if (mbd.isSingleton()) {//beanDefinition中指定該實例為單例
                //去工廠中獲取單例,如果沒有創建一個,然后添加到工廠中,否則直接返回
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
            else if (mbd.isPrototype()) {//原型方式,每次都創建一個新的實例
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }
            else {//其他方式,如目前主體無關,不贅述
            }
        }
        return (T) bean;
    }
 

   這個方法好長,真的好長,我還刪除了一些與當前主體無關的代碼呢,好吧,不要被嚇住,如果是自己寫的代碼,再長都很容易弄懂,類的繼承關系再復雜都能輕車熟路,那是因為我們都清楚的知道每一行的用意,看別人的代碼一樣,多看幾遍就明白了,再復雜都一樣。

    首先Spring會檢查beanName,獲取規范的beanName,然后它會檢查是否存在已經注冊的單例(查詢上面提到的singletonObjects映射表),如果有的話就直接返回了,一切就結束了,否則的話,會查看是否存在父工廠,如果有調用父工廠的getBean方法,如果沒有呢?

    好吧那就要着手創建實例了,首先查看beanDefinitionMap查找該beanName對應的beanDefinition實例,然后根據該實例判斷是否存在依賴關系,如果存在在遞歸的調用getBean方法,直到所有的依賴關系都正確的實例化和裝配完成,並且將這些依賴關系保存到上面提到的dependencyForBeanMap 和dependentBeanMap中。

    接下來,Spring查看BeanDefinition來確定該Bean應該是單例方式創建還是原型方式創建?如果是單例的話,Spring會調用getSingleton方法查找或創建一個單例(下面會詳聊),如果是原型的話,每次調用getBean方法都會創建一個新的實例,看上面代碼便會一清二楚了。

那下面我們就看看這個getSingleton方法做了什么?

?
6
 
  1. public Object getSingleton(String beanName, ObjectFactory singletonFactory) {  
  2.         //這不就是上面說的bean實例映射表嗎?哈,被同步了,保證線程安全啊  
  3.         synchronized (this.singletonObjects) {  
  4.             Object singletonObject = this.singletonObjects.get(beanName);  
  5.             if (singletonObject == null) {//第一次創建當然是空  
  6.                 beforeSingletonCreation(beanName);//這個是看看當前的beanName是否在排除列表中,如果是  
  7.                 //則拋出異常  
  8.                 boolean recordSuppressedExceptions = (this.suppressedExceptions == null);  
  9.                 try {//這里調用了上面的匿名內部類的getObject方法了,實則調用了createBean方法  
  10.                     singletonObject = singletonFactory.getObject();  
  11.                 }//這不,添加到了singleObjects映射表中了,以備下次使用  
  12.                 addSingleton(beanName, singletonObject);  
  13.             }  
  14.             return (singletonObject != NULL_OBJECT ? singletonObject : null);  
  15.         }  
  16.     }  
public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
        //這不就是上面說的bean實例映射表嗎?哈,被同步了,保證線程安全啊
        synchronized (this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {//第一次創建當然是空
                beforeSingletonCreation(beanName);//這個是看看當前的beanName是否在排除列表中,如果是
                //則拋出異常
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                try {//這里調用了上面的匿名內部類的getObject方法了,實則調用了createBean方法
                    singletonObject = singletonFactory.getObject();
                }//這不,添加到了singleObjects映射表中了,以備下次使用
                addSingleton(beanName, singletonObject);
            }
            return (singletonObject != NULL_OBJECT ? singletonObject : null);
        }
    }
 

   這里稍微清晰了,查看singletonObjects映射表,看是否存在已經注冊的單例,如果沒有調用createBean方法創建一個,並且注冊到singletonObjects映射表中,否則直接返回就Ok了。

下面就是createBean了, we are close。

?
 
 
  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,   
  2.                                                                     final Object[] args) {  
  3.         // Instantiate the bean.  
  4.         BeanWrapper instanceWrapper = null;  
  5.         if (mbd.isSingleton()) {  
  6.             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  
  7.         }  
  8.         if (instanceWrapper == null) {//實例化動作  
  9.             instanceWrapper = createBeanInstance(beanName, mbd, args);  
  10.         }  
  11.         //.....some codes we don't care.  
  12.         //......  
  13.         // Initialize the bean instance.  
  14.         Object exposedObject = bean;  
  15.         try {/////裝配動作  
  16.             populateBean(beanName, mbd, instanceWrapper);  
  17.             if (exposedObject != null) {//后面會講到,暫時不關心  
  18.                 exposedObject = initializeBean(beanName, exposedObject, mbd);  
  19.             }  
  20.         }  
  21.         //........some codes we don't care.  
  22.         return exposedObject;  
  23.     }  
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, 
                                                                    final Object[] args) {
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {//實例化動作
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        //.....some codes we don't care.
        //......
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {/////裝配動作
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {//后面會講到,暫時不關心
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }
        //........some codes we don't care.
        return exposedObject;
    }
 

   比較清晰(同樣去除了一些我們不關心的代碼),上面的方法分了我們期望的兩部執行,第一實例化Bean,第二裝配Bean。

    第一步實例化主要是通過確定調用的構造器來最終調用Class.newInstance(args)方法來實例化Bean。不做細究,有興趣可以自己看看,比較簡單,主要是第二部裝配,也就是處理我們的@Autowired注解(終於找到正題了)。

六、執行裝配

    方法populateBean執行了最終的Autowired動作,我們看一下它做了什么?話說這塊有點麻煩了,開始之前想講幾個比較重要的類和接口吧:

    A) PropertyValue:這是一個用來表示Bean屬性的對象,其中定義了屬性的名字和值等信息,如simpleService,和simpleDao屬性。

    B) PropertyDescriptor:這個事Bean屬性的描述符,其中定義了該屬性可能存在的setter和getter方法,以及所有Bean的Class對象。

    C) InjectionMetadata:這個是注入元數據,包含了目標Bean的Class對象,和注入元素(InjectionElement)集合.

    D) InjectionElement:這個是注入元素,包含了注入元素的Java.lang.reflect.Member 的對象,以及一個PropertyDescriptor對象。就是對java.lang.reflect.Member的一個封裝,用來執行最終的注入動作,它有兩個子類,分別是:AutowiredFieldElement表示字段屬性,AutowiredMethodElement表示方法。

    其實最終的目標就是將PropertyValue中的value值賦給InjectionElement中的Member對象。那它是怎么做的呢?

 
 
 
  1. protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {  
  2.         //嘗試從BeanDefinition中獲取PropertyValue的屬性集合,很明顯沒有值呢還。  
  3.         PropertyValues pvs = mbd.getPropertyValues();  
  4.         //.....其中執行了一些BeanPostProcessor的postProcessAfterInstantiation動作,我們不關心。  
  5.         //.....移除了  
  6.    
  7.         //這里比較重要,這里會設置上面的PropertyValues的值,默認情況下是getResolvedAutowiredMode方法返回  
  8.         //0, 但是我們可以在xml配置文件中設置<beans/>標簽的default-autowire屬性來改變它。  
  9.         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
  10.                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
  11.             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);  
  12.             // Add property values based on autowire by name if applicable.  
  13.             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {  
  14.                 autowireByName(beanName, mbd, bw, newPvs);  
  15.             }  
  16.             // Add property values based on autowire by type if applicable.  
  17.             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
  18.                 autowireByType(beanName, mbd, bw, newPvs);  
  19.             }  
  20.             pvs = newPvs;  
  21.         }  
  22.         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();  
  23.         boolean needsDepCheck = (mbd.getDependencyCheck() !=   
  24.                                                 RootBeanDefinition.DEPENDENCY_CHECK_NONE);  
  25.         if (hasInstAwareBpps || needsDepCheck) {  
  26.             PropertyDescriptor[] filteredPds =   
  27.                             filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);  
  28.             if (hasInstAwareBpps) {  
  29.                 //這里便是最最最重要的了,也就是最終的Autowired了。  
  30.                 for (BeanPostProcessor bp : getBeanPostProcessors()) {  
  31.                     if (bp instanceof InstantiationAwareBeanPostProcessor) {  
  32.                         InstantiationAwareBeanPostProcessor ibp =   
  33.                                                     (InstantiationAwareBeanPostProcessor) bp;  
  34.                         pvs = ibp.postProcessPropertyValues(//瞅到沒,這個方法哦~~~  
  35.                                         pvs, filteredPds, bw.getWrappedInstance(), beanName);  
  36.                         if (pvs == null) {  
  37.                             return;  
  38.                         }  
  39.                     }  
  40.                 }  
  41.             }  
  42.             if (needsDepCheck) {  
  43.                 checkDependencies(beanName, mbd, filteredPds, pvs);  
  44.             }  
  45.         }  
  46.         applyPropertyValues(beanName, mbd, bw, pvs);  
  47.     }  
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        //嘗試從BeanDefinition中獲取PropertyValue的屬性集合,很明顯沒有值呢還。
        PropertyValues pvs = mbd.getPropertyValues();
        //.....其中執行了一些BeanPostProcessor的postProcessAfterInstantiation動作,我們不關心。
        //.....移除了
 
        //這里比較重要,這里會設置上面的PropertyValues的值,默認情況下是getResolvedAutowiredMode方法返回
        //0, 但是我們可以在xml配置文件中設置<beans/>標簽的default-autowire屬性來改變它。
        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;
        }
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != 
                                                RootBeanDefinition.DEPENDENCY_CHECK_NONE);
        if (hasInstAwareBpps || needsDepCheck) {
            PropertyDescriptor[] filteredPds = 
                            filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            if (hasInstAwareBpps) {
                //這里便是最最最重要的了,也就是最終的Autowired了。
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = 
                                                    (InstantiationAwareBeanPostProcessor) bp;
                        pvs = ibp.postProcessPropertyValues(//瞅到沒,這個方法哦~~~
                                        pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
 

   Spring 嘗試獲取bean definition的PropertyValue集合,開始當然是空的,然后下面便是進行根據名字或者類型為我們的PropertyValue集合進行賦值了, 在不設置<beans default-autowire="byName/byType"/>的情況下是不會調用這個方法的,如果設置了byName,我們來看看做了什么?

?
  1. protected void autowireByName(  
  2.             String beanName, AbstractBeanDefinition mbd,   
  3.             BeanWrapper bw, MutablePropertyValues pvs) {  
  4.         //找到還沒賦值的屬性名稱,看下面方法  
  5.         String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);  
  6.         for (String propertyName : propertyNames) {  
  7.             if (containsBean(propertyName)) {  
  8.                 //遞歸調用getBean,如果沒有創建並注冊,有了直接返回。  
  9.                 Object bean = getBean(propertyName);  
  10.                 //將剛得到或創建的bean賦值給PropertyValue  
  11.                 pvs.add(propertyName, bean);  
  12.                 //並將該屬性名和實例注冊到依賴關系映射表dependentBeanMap和dependencyForBeanMap中  
  13.                 registerDependentBean(propertyName, beanName);  
  14.             }  
  15.         }  
  16.     }  
  17.    
  18. protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {  
  19.         Set<String> result = new TreeSet<String>();  
  20.         PropertyValues pvs = mbd.getPropertyValues();  
  21.         PropertyDescriptor[] pds = bw.getPropertyDescriptors();  
  22.         //遍歷bean的所有屬性,並將符合條件的屬性名添加到結果列表中  
  23.         for (PropertyDescriptor pd : pds) {  
  24.             if (pd.getWriteMethod() != null   
  25.                 && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&  
  26.                     !BeanUtils.isSimpleProperty(pd.getPropertyType())) {  
  27.                 result.add(pd.getName());  
  28.             }  
  29.         }  
  30.         return StringUtils.toStringArray(result);  
  31.     }  
protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, 
            BeanWrapper bw, MutablePropertyValues pvs) {
        //找到還沒賦值的屬性名稱,看下面方法
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            if (containsBean(propertyName)) {
                //遞歸調用getBean,如果沒有創建並注冊,有了直接返回。
                Object bean = getBean(propertyName);
                //將剛得到或創建的bean賦值給PropertyValue
                pvs.add(propertyName, bean);
                //並將該屬性名和實例注冊到依賴關系映射表dependentBeanMap和dependencyForBeanMap中
                registerDependentBean(propertyName, beanName);
            }
        }
    }
 
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
        Set<String> result = new TreeSet<String>();
        PropertyValues pvs = mbd.getPropertyValues();
        PropertyDescriptor[] pds = bw.getPropertyDescriptors();
        //遍歷bean的所有屬性,並將符合條件的屬性名添加到結果列表中
        for (PropertyDescriptor pd : pds) {
            if (pd.getWriteMethod() != null 
                && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                    !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
                result.add(pd.getName());
            }
        }
        return StringUtils.toStringArray(result);
    }
 

   上面兩段代碼的意思是,查看當前bean的所有屬性(描述符),然后依次判斷查找符合條件的屬性,並添加到屬性名稱數組中,然后遍歷這個數組,對其中的屬性名依次調用getBean(propertyName)方法來獲取或創建該名稱的bean實例,並將該bean實例設為PropertyValue的value值,最后添加到依賴關系映射表中(dependencyForBeanMap和dependentBeanMap)。好了此時PropertyValues有值了,后面就可以用它來注入到bean的屬性中了。我們接着看上面populateBean方法。

    PropertyValue值設置后,Spring會調用getBeanPostProcessor方法遍歷Bean工廠中注冊的所有BeanPostProcessor,其中就包括AutowiredAnnotationBeanPostProcessor(這些BeanPostProcessor都是系統默認硬編碼注冊到bean工廠中的)。接着就會調用AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法,並將之前的PropertyValues和bean實例傳遞進去。

?
  1. //雖然PropertyValues屬性傳遞過去了,但是並沒有使用它直接賦值給屬性變量(還不清楚為什么會傳遞它,其實沒用到)  
  2. @Override  
  3. public PropertyValues postProcessPropertyValues(PropertyValues pvs,   
  4.                 PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {  
  5.         //調用下面的方法獲取InjectionMetadata對象(其實InjectionElement集合)  
  6.         InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());  
  7.         try {  
  8.             metadata.inject(bean, beanName, pvs);  
  9.         }  
  10.         return pvs;  
  11.     }  
  12.    
  13. private InjectionMetadata findAutowiringMetadata(Class<?> clazz) {  
  14.         // 先找緩存  
  15.         InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);  
  16.         if (metadata == null) {  
  17.             synchronized (this.injectionMetadataCache) {  
  18.                 metadata = this.injectionMetadataCache.get(clazz);  
  19.                 if (metadata == null) {  
  20.                     //緩存沒有,調用buildAutowiringMetadata方法構建  
  21.                     metadata = buildAutowiringMetadata(clazz);  
  22.                     this.injectionMetadataCache.put(clazz, metadata);  
  23.                 }  
  24.             }  
  25.         }  
  26.         return metadata;  
  27.     }  
  28.    
  29. private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {  
  30.         LinkedList<InjectionMetadata.InjectedElement> elements =   
  31.                                         new LinkedList<InjectionMetadata.InjectedElement>();  
  32.         Class<?> targetClass = clazz;  
  33.         do {//這里一個循環,因為要考慮父類的字段和方法  
  34.             LinkedList<InjectionMetadata.InjectedElement> currElements =   
  35.                                     new LinkedList<InjectionMetadata.InjectedElement>();  
  36.             for (Field field : targetClass.getDeclaredFields()) {  
  37.                 //遍歷每一個field,找到被標記為@Autowired的field  
  38.                 Annotation annotation = findAutowiredAnnotation(field);  
  39.                 if (annotation != null) {  
  40.                     if (Modifier.isStatic(field.getModifiers())) {  
  41.                         continue;//不可一世static的。  
  42.                     }  
  43.                     boolean required = determineRequiredStatus(annotation);  
  44.                     //創建AutowiredFieldElement。  
  45.                     currElements.add(new AutowiredFieldElement(field, required));  
  46.                 }  
  47.             }  
  48.             for (Method method : targetClass.getDeclaredMethods()) {  
  49.                 //遍歷所有方法,這里有個橋方法的處理,我們不關心  
  50.                 Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);  
  51.                 Annotation annotation = BridgeMethodResolver  
  52.                                     .isVisibilityBridgeMethodPair(method, bridgedMethod) ?  
  53.                                         findAutowiredAnnotation(bridgedMethod) :  
  54.                                      findAutowiredAnnotation(method);  
  55.                 if (annotation != null &&   
  56.                             method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {  
  57.                     if (Modifier.isStatic(method.getModifiers())) {  
  58.                         continue;  
  59.                     }  
  60.                     if (method.getParameterTypes().length == 0) {  
  61.                     }  
  62.                     boolean required = determineRequiredStatus(annotation);  
  63.                     PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);  
  64.                     //創建AutowiredMethodElement。  
  65.                     currElements.add(new AutowiredMethodElement(method, required, pd));  
  66.                 }  
  67.             }  
  68.             elements.addAll(0, currElements);  
  69.             targetClass = targetClass.getSuperclass();  
  70.         }  
  71.         while (targetClass != null && targetClass != Object.class);  
  72.         //將InjectionElement集合添加到新建的InjectionMetadata中。  
  73.         return new InjectionMetadata(clazz, elements);  
  74.     }  
//雖然PropertyValues屬性傳遞過去了,但是並沒有使用它直接賦值給屬性變量(還不清楚為什么會傳遞它,其實沒用到)
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, 
                PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        //調用下面的方法獲取InjectionMetadata對象(其實InjectionElement集合)
        InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
        try {
            metadata.inject(bean, beanName, pvs);
        }
        return pvs;
    }
 
private InjectionMetadata findAutowiringMetadata(Class<?> clazz) {
        // 先找緩存
        InjectionMetadata metadata = this.injectionMetadataCache.get(clazz);
        if (metadata == null) {
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(clazz);
                if (metadata == null) {
                    //緩存沒有,調用buildAutowiringMetadata方法構建
                    metadata = buildAutowiringMetadata(clazz);
                    this.injectionMetadataCache.put(clazz, metadata);
                }
            }
        }
        return metadata;
    }
 
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
        LinkedList<InjectionMetadata.InjectedElement> elements = 
                                        new LinkedList<InjectionMetadata.InjectedElement>();
        Class<?> targetClass = clazz;
        do {//這里一個循環,因為要考慮父類的字段和方法
            LinkedList<InjectionMetadata.InjectedElement> currElements = 
                                    new LinkedList<InjectionMetadata.InjectedElement>();
            for (Field field : targetClass.getDeclaredFields()) {
                //遍歷每一個field,找到被標記為@Autowired的field
                Annotation annotation = findAutowiredAnnotation(field);
                if (annotation != null) {
                    if (Modifier.isStatic(field.getModifiers())) {
                        continue;//不可一世static的。
                    }
                    boolean required = determineRequiredStatus(annotation);
                    //創建AutowiredFieldElement。
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            }
            for (Method method : targetClass.getDeclaredMethods()) {
                //遍歷所有方法,這里有個橋方法的處理,我們不關心
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                Annotation annotation = BridgeMethodResolver
                                    .isVisibilityBridgeMethodPair(method, bridgedMethod) ?
                                        findAutowiredAnnotation(bridgedMethod) :
                                     findAutowiredAnnotation(method);
                if (annotation != null && 
                            method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
                    if (Modifier.isStatic(method.getModifiers())) {
                        continue;
                    }
                    if (method.getParameterTypes().length == 0) {
                    }
                    boolean required = determineRequiredStatus(annotation);
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
                    //創建AutowiredMethodElement。
                    currElements.add(new AutowiredMethodElement(method, required, pd));
                }
            }
            elements.addAll(0, currElements);
            targetClass = targetClass.getSuperclass();
        }
        while (targetClass != null && targetClass != Object.class);
        //將InjectionElement集合添加到新建的InjectionMetadata中。
        return new InjectionMetadata(clazz, elements);
    }
 

   上面三個方法看似復雜其實很簡單,首先Spring嘗試調用findAutowiringMetadata方法獲取該bean的InjectionMetadata實例(也就是有哪些屬性需要被自動裝配,也就是查找被@Autowired注解標記的元素)。怎么獲取呢?首先去緩存里面找,找不到就遍歷bean的和父類的字段域和方法,如果別標記為@Autowired並且不是靜態的就添加到InjectionMetadata中,並添加到緩存中(各種緩存啊)。獲得InjectionMetadata對象后便遍歷其中的所有InjectionElement對象,調用其中的inject方法。前面說了InjectionElement有兩個實現類,我們只看一個就可以,因為基本相同:

?
  1. @Override  
  2.         protected void inject(Object bean, String beanName, PropertyValues pvs)   
  3.                                                             throws Throwable {  
  4.             Field field = (Field) this.member;  
  5.             try {  
  6.                 Object value;  
  7.                 if (this.cached) {  
  8.                     value = resolvedCachedArgument(beanName, this.cachedFieldValue);  
  9.                 }  
  10.                 else {  
  11.                     DependencyDescriptor descriptor   
  12.                                         = new DependencyDescriptor(field, this.required);  
  13.                     Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);  
  14.                     TypeConverter typeConverter = beanFactory.getTypeConverter();  
  15.                     //這里是重中之重,獲取真正的屬性值。  
  16.                     value = beanFactory.resolveDependency(descriptor, beanName,   
  17.                                                 autowiredBeanNames, typeConverter);  
  18.                 }  
  19.                 if (value != null) {  
  20.                     ReflectionUtils.makeAccessible(field);  
  21.                     field.set(bean, value);//最終賦值結束。  
  22.                 }  
  23.             }  
  24.         }  
  25.     }  
@Override
        protected void inject(Object bean, String beanName, PropertyValues pvs) 
                                                            throws Throwable {
            Field field = (Field) this.member;
            try {
                Object value;
                if (this.cached) {
                    value = resolvedCachedArgument(beanName, this.cachedFieldValue);
                }
                else {
                    DependencyDescriptor descriptor 
                                        = new DependencyDescriptor(field, this.required);
                    Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
                    TypeConverter typeConverter = beanFactory.getTypeConverter();
                    //這里是重中之重,獲取真正的屬性值。
                    value = beanFactory.resolveDependency(descriptor, beanName, 
                                                autowiredBeanNames, typeConverter);
                }
                if (value != null) {
                    ReflectionUtils.makeAccessible(field);
                    field.set(bean, value);//最終賦值結束。
                }
            }
        }
    }
 

  可以看到,雖然PropertyValues屬性傳遞過去了,但是並沒有使用它直接賦值給屬性變量(還不清楚為什么會傳遞它,其實沒用到),而是通過調用bean工廠的resolveDependency方法來獲取屬性值得。那我們看一下resolveDependency做了什么?

?
  1. protected Object doResolveDependency(DependencyDescriptor descriptor,   
  2.                                         Class<?> type, String beanName,  
  3.                                      Set<String> autowiredBeanNames,   
  4.                                 TypeConverter typeConverter) throws BeansException  {  
  5.         if (type.isArray()) {//如果屬性類型是數組  
  6.             Class<?> componentType = type.getComponentType();  
  7.             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor);  
  8.             if (autowiredBeanNames != null) {  
  9.                 autowiredBeanNames.addAll(matchingBeans.keySet());  
  10.             }  
  11.             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());  
  12.             return converter.convertIfNecessary(matchingBeans.values(), type);  
  13.         }//如果屬性是集合,並且是接口  
  14.         else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {  
  15.             Class<?> elementType = descriptor.getCollectionType();  
  16.             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, descriptor);  
  17.             if (autowiredBeanNames != null) {  
  18.                 autowiredBeanNames.addAll(matchingBeans.keySet());  
  19.             }  
  20.             TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());  
  21.             return converter.convertIfNecessary(matchingBeans.values(), type);  
  22.         }//如果屬性是Map並且是接口  
  23.         else if (Map.class.isAssignableFrom(type) && type.isInterface()) {  
  24.             Class<?> keyType = descriptor.getMapKeyType();  
  25.             Class<?> valueType = descriptor.getMapValueType();  
  26.             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);  
  27.             if (autowiredBeanNames != null) {  
  28.                 autowiredBeanNames.addAll(matchingBeans.keySet());  
  29.             }  
  30.             return matchingBeans;  
  31.         }//自定義類型了  
  32.         else {//都調用了這個方法  
  33.             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);  
  34.             if (matchingBeans.size() > 1) {  
  35.                 String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor);  
  36.                 if (autowiredBeanNames != null) {  
  37.                     autowiredBeanNames.add(primaryBeanName);  
  38.                 }  
  39.                 return matchingBeans.get(primaryBeanName);  
  40.             }  
  41.             // We have exactly one match.  
  42.             Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();  
  43.             if (autowiredBeanNames != null) {  
  44.                 autowiredBeanNames.add(entry.getKey());  
  45.             }  
  46.             return entry.getValue();  
  47.         }  
  48.     }  
protected Object doResolveDependency(DependencyDescriptor descriptor, 
                                        Class<?> type, String beanName,
                                     Set<String> autowiredBeanNames, 
                                TypeConverter typeConverter) throws BeansException  {
        if (type.isArray()) {//如果屬性類型是數組
            Class<?> componentType = type.getComponentType();
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor);
            if (autowiredBeanNames != null) {
                autowiredBeanNames.addAll(matchingBeans.keySet());
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            return converter.convertIfNecessary(matchingBeans.values(), type);
        }//如果屬性是集合,並且是接口
        else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
            Class<?> elementType = descriptor.getCollectionType();
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, descriptor);
            if (autowiredBeanNames != null) {
                autowiredBeanNames.addAll(matchingBeans.keySet());
            }
            TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
            return converter.convertIfNecessary(matchingBeans.values(), type);
        }//如果屬性是Map並且是接口
        else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
            Class<?> keyType = descriptor.getMapKeyType();
            Class<?> valueType = descriptor.getMapValueType();
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);
            if (autowiredBeanNames != null) {
                autowiredBeanNames.addAll(matchingBeans.keySet());
            }
            return matchingBeans;
        }//自定義類型了
        else {//都調用了這個方法
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            if (matchingBeans.size() > 1) {
                String primaryBeanName = determinePrimaryCandidate(matchingBeans, descriptor);
                if (autowiredBeanNames != null) {
                    autowiredBeanNames.add(primaryBeanName);
                }
                return matchingBeans.get(primaryBeanName);
            }
            // We have exactly one match.
            Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
            if (autowiredBeanNames != null) {
                autowiredBeanNames.add(entry.getKey());
            }
            return entry.getValue();
        }
    }
 

   這個方法其實就是根據類型到bean工廠中查找類型匹配的bean實例,然后就看到了這幾個條件分支語句,如果是數組,集合,映射表,自定義類型都執行了差不多的操作,findAutowireCandidate方法。這個方法會去工廠中執行類型匹配的查找,將匹配的結果集返回,不同的是,集合數組類型會通過TypeConverter進行結果的轉換。

    到此為止,找到了屬性的匹配值,然后反射賦值就完成了整個的自動裝配過程。可以看出,@Autowired是通過類型來進行自動裝配的。

    上面是屬性的賦值過程也就是InjectionFieldElement的inject方法,InjectionMethodElement的inject方法大致相同只是對每一個方法參數執行一次resolveDependency方法來獲取參數值,然后反射執行方法。

    到此為止,整個實例化和裝配過程也就講完了,我們總結一下:

1)一切都是從bean工廠的getBean方法開始的,一旦該方法調用總會返回一個bean實例,無論當前是否存在,不存在就實例化一個並裝配,否則直接返回。

2)實例化和裝配過程中會多次遞歸調用getBean方法來解決類之間的依賴。

3)Spring幾乎考慮了所有可能性,所以方法特別復雜但完整有條理。

4)@Autowired最終是根據類型來查找和裝配元素的,但是我們設置了<beans default-autowire="byName"/>后會影響最終的類型匹配查找。因為在前面有根據BeanDefinition的autowire類型設置PropertyValue值得一步,其中會有新實例的創建和注冊。就是那個autowireByName方法。

七、一切的開始

    我們上面講完了整個Autowire過程了。那么,還有一個問題,上一篇我們知道了什么時候執行的配置文件讀取和組件掃描,但Spring MVC是在什么時候開始執行真個實例化過程的呢?很簡單就在組件掃描完成之后,bean工廠的refresh方法中(還記得嗎?)

?
 
 
  1. public void refresh() throws BeansException, IllegalStateException {  
  2.         synchronized (this.startupShutdownMonitor) {  
  3.             prepareRefresh();  
  4.             //前面說過,這里面執行了,組件掃描和配置文件讀取  
  5.             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
  6.             prepareBeanFactory(beanFactory);  
  7.             try {  
  8.                 postProcessBeanFactory(beanFactory);  
  9.                 invokeBeanFactoryPostProcessors(beanFactory);  
  10.                 //這里注冊了BeanPostProcessor,包括AutowiredAnnotationBeanPostProcessor  
  11.                 registerBeanPostProcessors(beanFactory);  
  12.                 initMessageSource();  
  13.                 initApplicationEventMulticaster();  
  14.                 onRefresh();  
  15.                 registerListeners();  
  16.                 //這里就執行了所有非延遲加載的實例化工作。//here  
  17.                 finishBeanFactoryInitialization(beanFactory);  
  18.                 finishRefresh();  
  19.             }  
  20.         }  
  21.     }  
public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            prepareRefresh();
            //前面說過,這里面執行了,組件掃描和配置文件讀取
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            prepareBeanFactory(beanFactory);
            try {
                postProcessBeanFactory(beanFactory);
                invokeBeanFactoryPostProcessors(beanFactory);
                //這里注冊了BeanPostProcessor,包括AutowiredAnnotationBeanPostProcessor
                registerBeanPostProcessors(beanFactory);
                initMessageSource();
                initApplicationEventMulticaster();
                onRefresh();
                registerListeners();
                //這里就執行了所有非延遲加載的實例化工作。//here
                finishBeanFactoryInitialization(beanFactory);
                finishRefresh();
            }
        }
    }
 

   就是上面的finishBeanFactoryInitialization方法執行了裝配工作,該方法會調用bean工廠的preInstantiateSingletons方法,這個方法會遍歷所有注冊的bean definition實例,如果是單例並且是非延遲加載的就調用getBean方法。

    好了,到此為止我們就清晰的了解了,Spring MVC的實例化和自動裝配工作了,如有問題歡迎評論中提出,我們一起討論。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM