1. 程式人生 > >spring原始碼學習(二)

spring原始碼學習(二)

本篇文章,來介紹finishBeanFactoryInitialization(beanFactory);這個方法主要是完成bean的例項化,

invokeBeanFactoryPostProcessors(beanFactory);負責把所有的bean掃描到beanDefinitionMap中;

 

下面來說是如何初始化的

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

我們直接從這個方法開始說起,前面的呼叫鏈簡單,就不說了

 1 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
 2             @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
 3 
 4     /**
 5      * 通過name獲取beanName,這裡不使用name直接作為beanName有兩個原因:
 6      *  1.name可能是以&開頭的,表明呼叫者想獲取FactoryBean本身,而非FactoryBean;在beanFactory中factoryBean的儲存也是map格式
 7      *    <beanName,bean> 只是說,普通的beanName是沒有&這個字串的,所以,需要將name的首字母移除,這樣才能從快取中拿到factoryBean
 8      *  2.還是別名的問題,需要轉換
 9      */
10     final String beanName = transformedBeanName(name);
11     Object bean;
12 
13     /**
14      * 1.從單例池中獲取當前bean
15      * 2.這裡是迴圈依賴的重要方法之一
16      *
17      */
18     // Eagerly check singleton cache for manually registered singletons.
19     Object sharedInstance = getSingleton(beanName);
20     if (sharedInstance != null && args == null) {
21         if (logger.isDebugEnabled()) {
22             if (isSingletonCurrentlyInCreation(beanName)) {
23                 logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
24                         "' that is not fully initialized yet - a consequence of a circular reference");
25             }
26             else {
27                 logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
28             }
29         }
30         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
31     }
32 
33     else {
34         // Fail if we're already creating this bean instance:
35         // We're assumably within a circular reference.
36         /**
37          * 這裡判斷bean是否在建立過程中,是第二次呼叫的時候 才會判斷;如果是第一次執行到這裡,set集合是空(這裡判斷的是原型bean)
38          */
39         if (isPrototypeCurrentlyInCreation(beanName)) {
40             throw new BeanCurrentlyInCreationException(beanName);
41         }
42 
43         //新增到alreadyCreated集合當中,表示當前bean已經建立過一次了
44         if (!typeCheckOnly) {
45             markBeanAsCreated(beanName);
46         }
47 
48         try {
49             final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
50             checkMergedBeanDefinition(mbd, beanName, args);
51 
52             // Guarantee initialization of beans that the current bean depends on.
53             String[] dependsOn = mbd.getDependsOn();
54             if (dependsOn != null) {
55                 for (String dep : dependsOn) {
56                     if (isDependent(beanName, dep)) {
57                         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
58                                 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
59                     }
60                     registerDependentBean(dep, beanName);
61                     try {
62                         getBean(dep);
63                     }
64                     catch (NoSuchBeanDefinitionException ex) {
65                         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
66                                 "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
67                     }
68                 }
69             }
70 
71             // Create bean instance.如果當前bean是單例項的,就呼叫createBean
72             if (mbd.isSingleton()) {
73                 sharedInstance = getSingleton(beanName, () -> {
74                     try {
75                         return createBean(beanName, mbd, args);
76                     }
77                     catch (BeansException ex) {
78                         // Explicitly remove instance from singleton cache: It might have been put there
79                         // eagerly by the creation process, to allow for circular reference resolution.
80                         // Also remove any beans that received a temporary reference to the bean.
81                         destroySingleton(beanName);
82                         throw ex;
83                     }
84                 });
85                 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
86             }
87         }
88         catch (BeansException ex) {
89             cleanupAfterBeanCreationFailure(beanName);
90             throw ex;
91         }
92     }
93 
94 
95     return (T) bean;
96 }

粘貼出來的方法刪減了一部分程式碼,我們只說單例項bean的初始化;

在判斷當前bean是單例項的時候,會呼叫createBean;在getSingleton這裡,有一行程式碼,是把當前bean新增到一個set集合中(這個set集合表示當前bean正在建立過程中),

這個set是用來解決迴圈依賴問題的,在後面,會單獨抽出一篇來介紹迴圈引用是如何解決的,在這裡就先跳過;

 

在createBean的方法中,會呼叫createBeanInstance(beanName, mbd, args); 這個方法主要是完成bean的初始化,在方法中會呼叫org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors;

這個後置處理器的determineCandidateConstructors方法來推斷使用哪個建構函式來初始化;

這個方法裡面,我目前也正在學習,後續會貼出對這個方法的學習筆記,這裡先暫時跳過;(我們就認為createBeanInstance方法完成了bean的建立),

推斷出使用哪個建構函式之後,會初始化bean,返回的是一個BeanWrapper物件。這裡創建出來的僅僅是bean物件;需要經過後面的屬性注入,以及初始化,才會變成我們所說的spring bean物件;

 

 1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
 2             throws BeanCreationException {
 3 
 4     // Instantiate the bean.
 5     BeanWrapper instanceWrapper = null;
 6     if (mbd.isSingleton()) {
 7         instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 8     }
 9     if (instanceWrapper == null) {
10         /**
11          *  建立bean例項,並將bean例項包裹在BeanWrapper實現類物件中返回,
12          *  createBeanInstance中包含三種建立bean的方式
13          *    1.通過工廠方法建立bean例項
14          *    2.通過構造方法自動注入的方式建立bean例項
15          *    3.通過無參構造方法建立bean例項
16          *
17          *  如果bean的配置中配置了lookup-method和replace-method  則會使用增強bean例項
18          *
19          * 在這個方法中完成了對bean的建立(僅僅是new出來,也就是說在這個方法裡面推斷要使用哪個建構函式來建立bean物件)
20          * 然後完成bean的初始化
21          *
22          */
23         instanceWrapper = createBeanInstance(beanName, mbd, args);
24     }
25     final Object bean = instanceWrapper.getWrappedInstance();
26     Class<?> beanType = instanceWrapper.getWrappedClass();
27     if (beanType != NullBean.class) {
28         mbd.resolvedTargetType = beanType;
29     }
30 
31     // Allow post-processors to modify the merged bean definition.
32     synchronized (mbd.postProcessingLock) {
33         if (!mbd.postProcessed) {
34             try {
35                 //mpy 第三次呼叫後置處理器  快取註解資訊
36                 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
37             }
38             catch (Throwable ex) {
39                 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
40                         "Post-processing of merged bean definition failed", ex);
41             }
42             mbd.postProcessed = true;
43         }
44     }
45 
46     // Eagerly cache singletons to be able to resolve circular references
47     // even when triggered by lifecycle interfaces like BeanFactoryAware.
48     boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
49             isSingletonCurrentlyInCreation(beanName));
50     if (earlySingletonExposure) {
51         if (logger.isDebugEnabled()) {
52             logger.debug("Eagerly caching bean '" + beanName +
53                     "' to allow for resolving potential circular references");
54         }
55         //mpy 第四次呼叫後置處理器 獲取一個提前暴露的物件  用來解決迴圈依賴
56         addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
57     }
58 
59     // Initialize the bean instance.
60     Object exposedObject = bean;
61     try {
62         //在populateBean(beanName, mbd, instanceWrapper);方法中完成第五次第六次呼叫後置處理器
63         populateBean(beanName, mbd, instanceWrapper);
64         //在initialzeBean中完成第七次第八次後置處理器呼叫
65         exposedObject = initializeBean(beanName, exposedObject, mbd);
66     }
67     catch (Throwable ex) {
68         if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
69             throw (BeanCreationException) ex;
70         }
71         else {
72             throw new BeanCreationException(
73                     mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
74         }
75     }
76     return exposedObject;
77 }

 

上面這個方法中,呼叫第四次後置處理器這裡,返回了一個object物件,這個方法是為了完成迴圈依賴的,放到後面一起講,

在populateBean中,會完成屬性的注入,比如@AutoWired,@Value這個屬性值注入

initializeBean方法,主要是呼叫bean的初始化方法

  bean的初始化有三種方式:

   1.@Bean註解中指定 initMethod destroyMethod

   2.@PostConstruct @PreDestroy

   3.實現DisposableBean和InitializingBean介面

 

 

在方法執行完之後,會把建立好的bean物件存放到singletonObjects這個map中,這個map存放的是所有例項化好的物件;如果bean是原型的,在第二次getBean的時候,會從這個map中獲取到bean物件

 

從狹義上來講,singletonObjects就是我們所說的spring容器

&n