【spring源碼分析】IOC容器初始化(六)

前言:通過前幾篇文章的講解,咱們已經獲得了BeanDefinition,接下來將分析Bean的加載。緩存


獲取Bean的入口:AbstractApplicationContext#getBeanless

1     public Object getBean(String name) throws BeansException {
2         // 檢測bean工廠是否存活
3         assertBeanFactoryActive();
4         return getBeanFactory().getBean(name);
5     }

分析:
首先檢查BeanFactory是否存活,還記得以前分析過的
prepareRefresh()方法嗎?若是不記得了,請翻看以前的文章,那裏設置了active的值,而後在這裏作檢查。若是BeanFactory關閉,則拋出異常。ide

1     protected void assertBeanFactoryActive() {
2         if (!this.active.get()) {
3             if (this.closed.get()) {
4                 throw new IllegalStateException(getDisplayName() + " has been closed already");
5             } else {
6                 throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
7             }
8         }
9     }

AbstractBeanFactory#getBean

1 @Override
2     public Object getBean(String name) throws BeansException {
3         return doGetBean(name, null, null, false);
4     }

最終切入點:函數

  1 // AbstractBeanFactory
  2 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
  3                               @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
  4 
  5         // 返回bean名稱,剝離工廠引用前綴
  6         // 若是name是alias,則獲取對應映射的beanName
  7         final String beanName = transformedBeanName(name);
  8         Object bean;
  9 
 10         // 從緩存或實例工廠中獲取Bean對象
 11         // Eagerly check singleton cache for manually registered singletons.
 12         Object sharedInstance = getSingleton(beanName);
 13         if (sharedInstance != null && args == null) {
 14             if (logger.isTraceEnabled()) {
 15                 if (isSingletonCurrentlyInCreation(beanName)) {
 16                     logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
 17                                          "' that is not fully initialized yet - a consequence of a circular reference");
 18                 } else {
 19                     logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
 20                 }
 21             }
 22             // 完成FactoryBean的相關處理,並用來獲取FactoryBean的處理結果
 23             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
 24         } else {
 25             // Fail if we're already creating this bean instance:
 26             // We're assumably within a circular reference.
 27             // Spring只能解決單例模式下的循環依賴,在原型模式下若是存在循環依賴則拋出異常
 28             // 這裏檢測原型模式下,該bean是否在加載,若是在加載則拋出異常
 29             if (isPrototypeCurrentlyInCreation(beanName)) {
 30                 throw new BeanCurrentlyInCreationException(beanName);
 31             }
 32 
 33             // 若是當前容器中沒有找到,則從父類容器中加載
 34             // Check if bean definition exists in this factory.
 35             BeanFactory parentBeanFactory = getParentBeanFactory();
 36             /**
 37              * 調用{@link DefaultListableBeanFactory#containsBeanDefinition(String)}方法
 38              * 其實就是在beanDefinitionMap中判斷是否存在beanName對應的BeanDefinition
 39              */
 40             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
 41                 // Not found -> check parent.
 42                 // 肯定原始的beanName
 43                 String nameToLookup = originalBeanName(name);
 44                 // 若是父類容器爲AbstractBeanFactory,則委託父類處理
 45                 if (parentBeanFactory instanceof AbstractBeanFactory) {
 46                     return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
 47                             nameToLookup, requiredType, args, typeCheckOnly);
 48                 } else if (args != null) { // 用明確的args從parentBeanFactory中,獲取Bean對象
 49                     // Delegation to parent with explicit args.
 50                     // 委託給父類構造函數getBean()處理
 51                     return (T) parentBeanFactory.getBean(nameToLookup, args);
 52                 } else if (requiredType != null) { // 用明確的requiredType從parentBeanFactory中,獲取Bean對象
 53                     // No args -> delegate to standard getBean method.
 54                     // 沒有args,委託給標準的getBean()處理
 55                     return parentBeanFactory.getBean(nameToLookup, requiredType);
 56                 } else {
 57                     // 直接使用nameToLookup從parentBeanFactory中獲取Bean對象
 58                     return (T) parentBeanFactory.getBean(nameToLookup);
 59                 }
 60             }
 61 
 62             // 若是不只僅是作類型檢查,而是建立bean,這裏須要記錄
 63             if (!typeCheckOnly) {
 64                 markBeanAsCreated(beanName);
 65             }
 66 
 67             try {
 68                 /**
 69                  * 從容器中獲取beanName對應的GenericBeanDefinition對象,並轉換成RootBeanDefinition對象
 70                  * GenericBeanDefinition的建立{@link BeanDefinitionReaderUtils#createBeanDefinition}方法
 71                  */
 72                 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
 73                 // 檢查合併的BeanDefinition
 74                 checkMergedBeanDefinition(mbd, beanName, args);
 75 
 76                 // Guarantee initialization of beans that the current bean depends on.
 77                 // 處理所依賴的bean
 78                 String[] dependsOn = mbd.getDependsOn();
 79                 if (dependsOn != null) {
 80                     for (String dep : dependsOn) {
 81                         // 若給定的依賴bean已經註冊爲依賴給定的bean
 82                         // 即循環依賴狀況,拋出BeanCreationException異常
 83                         if (isDependent(beanName, dep)) {
 84                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 85                                                             "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
 86                         }
 87                         // 緩存依賴調用
 88                         registerDependentBean(dep, beanName);
 89                         try {
 90                             // 遞歸處理依賴 Bean
 91                             getBean(dep);
 92                         } catch (NoSuchBeanDefinitionException ex) {
 93                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 94                                                             "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
 95                         }
 96                     }
 97                 }
 98                 // bean實例化
 99                 // Create bean instance.
100                 // 單例模式
101                 /**
102                  * 這裏有個已建立bean的重要方法createBean
103                  * {@link AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])}
104                  */
105                 if (mbd.isSingleton()) {
106                     sharedInstance = getSingleton(beanName, () -> {
107                         try {
108                             return createBean(beanName, mbd, args);
109                         } catch (BeansException ex) {
110                             // Explicitly remove instance from singleton cache: It might have been put there
111                             // eagerly by the creation process, to allow for circular reference resolution.
112                             // Also remove any beans that received a temporary reference to the bean.
113                             // 顯式從單例緩存中刪除Bean實例
114                             // 由於單例模式下爲了解決循環依賴,可能它已經存在,因此銷燬它
115                             destroySingleton(beanName);
116                             throw ex;
117                         }
118                     });
119                     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
120                 } else if (mbd.isPrototype()) { // 原型模式
121                     // It's a prototype -> create a new instance.
122                     Object prototypeInstance = null;
123                     try {
124                         // 前置處理
125                         beforePrototypeCreation(beanName);
126                         /**
127                          * 建立bean {@link AbstractAutowireCapableBeanFactory#createBean}
128                          */
129                         prototypeInstance = createBean(beanName, mbd, args);
130                     } finally {
131                         /**
132                          * 後置處理 與前置處理相反從{@link prototypesCurrentlyInCreation}中移除
133                          */
134                         afterPrototypeCreation(beanName);
135                     }
136                     bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
137                 } else { //其餘做用域
138                     // 得到scopeName對應的Scope對象
139                     String scopeName = mbd.getScope();
140                     final Scope scope = this.scopes.get(scopeName);
141                     if (scope == null) {
142                         throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
143                     }
144                     try {
145                         /**
146                          * 從指定的scope下建立bean
147                          * {@link SimpleThreadScope#get方法}
148                          */
149                         Object scopedInstance = scope.get(beanName, () -> {
150                             beforePrototypeCreation(beanName);
151                             try {
152                                 return createBean(beanName, mbd, args);
153                             } finally {
154                                 afterPrototypeCreation(beanName);
155                             }
156                         });
157                         bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
158                     } catch (IllegalStateException ex) {
159                         throw new BeanCreationException(beanName,
160                                                         "Scope '" + scopeName + "' is not active for the current thread; consider " +
161                                                                 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
162                                                         ex);
163                     }
164                 }
165             } catch (BeansException ex) {
166                 cleanupAfterBeanCreationFailure(beanName);
167                 throw ex;
168             }
169         }
170 
171         // 檢查須要的類型是否符合bean的實際類型
172         // Check if required type matches the type of the actual bean instance.
173         if (requiredType != null && !requiredType.isInstance(bean)) {
174             try {
175                 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
176                 if (convertedBean == null) {
177                     throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
178                 }
179                 return convertedBean;
180             } catch (TypeMismatchException ex) {
181                 if (logger.isTraceEnabled()) {
182                     logger.trace("Failed to convert bean '" + name + "' to required type '" +
183                                          ClassUtils.getQualifiedName(requiredType) + "'", ex);
184                 }
185                 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
186             }
187         }
188         return (T) bean;
189     }

分析:post

這裏的代碼稍微有點多,可是這段代碼很是重要,咱們一步步來進行分析。ui

AbstractBeanFactory#transformedBeanName

 1 public String canonicalName(String name) {
 2         String canonicalName = name;
 3         // Handle aliasing...
 4         String resolvedName;
 5         // 循環,從aliasMap中獲取最終的beanName
 6         do {
 7             resolvedName = this.aliasMap.get(canonicalName);
 8             if (resolvedName != null) {
 9                 canonicalName = resolvedName;
10             }
11         }
12         while (resolvedName != null);
13         return canonicalName;
14     }
15 
16 // BeanFactoryUtils
17 public static String transformedBeanName(String name) {
18         Assert.notNull(name, "'name' must not be null");
19 
20         // 若是beanName不是以"&"開始,則直接返回
21         if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
22             return name;
23         }
24         // computeIfAbsent方法,分兩種狀況:
25         // #1.不存在,則執行後面的lambda表達式,beanName的值就是name的值,並將結果添加到緩存。
26         // #2.存在,則直接返回name的值。
27         return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
28             do {
29                 beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
30             }
31             while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
32             return beanName;
33         });
34     }

分析:this

transformedBeanName函數的功能:返回beanName,剝離工廠引用前綴。spa

在BeanFactoryUtils#transformedBeanName中:prototype

  • 若是beanName不是以"&"開始,則直接返回。
  • 若是transformedBeanNameCache緩存中存在已經解析好的beanName,則直接返回。
  • 不存在,則剝離"&"符號後,將beanName加入緩存,而後再返回beanName。
  • SimpleAliasRegistry#canonicalName中循環從aliasMap中獲取最終的beanName。

DefaultSingletonBeanRegistry#getSingleton

 1 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
 2         // 從單例緩存中加載Bean
 3         Object singletonObject = this.singletonObjects.get(beanName);
 4         // 緩存中bean爲空,且當前bean正在建立
 5         if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
 6             // 作同步
 7             synchronized (this.singletonObjects) {
 8                 // 從earlySingletonObjects集合中獲取
 9                 singletonObject = this.earlySingletonObjects.get(beanName);
10                 // earlySingletonObjects集合中沒有,其容許提早建立
11                 if (singletonObject == null && allowEarlyReference) {
12                     // 從singletonFactories中獲取對應的ObjectFactory
13                     ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
14                     if (singletonFactory != null) {
15                         // 獲取bean
16                         singletonObject = singletonFactory.getObject();
17                         // 將bean添加到earlySingletonObjects集合中
18                         this.earlySingletonObjects.put(beanName, singletonObject);
19                         // 從singletonFactories中移除對應的
20                         this.singletonFactories.remove(beanName);
21                     }
22                 }
23             }
24         }
25         return singletonObject;
26     }

分析:code

在加載bean時,首先從單例緩存中獲取bean對象。

  • 首先從單例緩存中獲取bean對象,若是緩存中存在bean對象則直接返回(單例模式的bean在建立過程當中會進行緩存[singletonObjects])。
  • 若是緩存中bean對象爲空,且當前bean正在建立,則從earlySingletonObjects中獲取。
  • 若是earlySingletonObjects集合中不存在,且容許提早建立bean,則從singletonFactories中獲取單例工廠,若singleFactory不爲空,則經過getObject方法獲取bean,並將bean對象加入到earlySingletonObjects集合中,而後從singleFactory集合中移除對應的單例工廠對象。

注意這裏涉及到三個集合:

  • singletonObjects (一級)單例對象 Cache
  • earlySingletonObjects (二級)提早曝光的單例對象 Cache
  • singletonFactories (三級)單例對象工廠 Cache
 1 /**
 2      * Cache of singleton objects: bean name to bean instance.
 3      * 存放的是單例 bean 的映射。
 4      * <p>
 5      * 對應關係爲 bean name --> bean instance
 6      */
 7     private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
 8 
 9     /**
10      * Cache of singleton factories: bean name to ObjectFactory.<br/>
11      * 存放的是 ObjectFactory,能夠理解爲建立單例 bean 的 factory 。
12      * <p>
13      * 對應關係是 bean name --> ObjectFactory
14      */
15     private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
16 
17     /**
18      * Cache of early singleton objects: bean name to bean instance.<br/>
19      * 存放的是早期的 bean,對應關係也是 bean name --> bean instance。
20      * <p>
21      * 它與 {@link #singletonFactories} 區別在於 earlySingletonObjects 中存放的 bean 不必定是完整。
22      * <p>
23      * 從 {@link #getSingleton(String)} 方法中,咱們能夠了解,bean 在建立過程當中就已經加入到 earlySingletonObjects 中了。
24      * 因此當在 bean 的建立過程當中,就能夠經過 getBean() 方法獲取。
25      * <p>
26      * 這個 Map 也是【循環依賴】的關鍵所在。
27      */
28     private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

這三個緩存集合就是解決Spring中循環依賴的所在,具體流程:

  • 首先從一級緩存singletonObjects中獲取,若是爲null,且當前bean正在被建立,則從二級緩存earlySingletonObjects中獲取,若是仍是爲null,且容許singletonFactories經過getObject獲取,則從三級緩存singletonFactories中獲取,若是獲得,則將其加入二級緩存earlySingletonObjects中,並從三級緩存singletonFactories中移除對應的工廠對象(由於單例模式的bean只會被建立一次),這樣三級緩存就升級到二級緩存了,因此二級緩存存在的意義就是緩存三級緩存中ObjectFactory#getObject的執行結果,提早曝光單例Bean對象。

若是從單例緩存中獲得bean對象,則會調用getObjectForBeanInstance方法進一步處理,由於從緩存中獲得的bean是最原始的bean,並不必定是最終所須要的bean對象。

AbstractAutowireCapableBeanFactory#getObjectForBeanInstance

 1     protected Object getObjectForBeanInstance(
 2             Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
 3 
 4         String currentlyCreatedBean = this.currentlyCreatedBean.get();
 5         if (currentlyCreatedBean != null) {
 6             registerDependentBean(beanName, currentlyCreatedBean);
 7         }
 8 
 9         return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
10     }

分析:

  • 首先若是bean正在被建立,則會註冊依賴關係(registerDependentBean,該函數還未仔細分析,後續查漏補缺)。
  • 而後調用父類的getObjectForBeanInstance方法獲取Bean對象。

AbstractBeanFactory#getObjectForBeanInstance

 1 protected Object getObjectForBeanInstance(
 2             Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
 3 
 4         // 若是name是工廠類的引用名稱(name以"&"開頭)
 5         // Don't let calling code try to dereference the factory if the bean isn't a factory.
 6         if (BeanFactoryUtils.isFactoryDereference(name)) {
 7             // 若是是NullBean則直接返回
 8             if (beanInstance instanceof NullBean) {
 9                 return beanInstance;
10             }
11             // 若是beanInstance不是FactoryBean則拋出異常
12             if (!(beanInstance instanceof FactoryBean)) {
13                 throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
14             }
15         }
16 
17         // 走到這裏,說明咱們如今已經有一個Bean實例,固然該實例可能會是一個正常的Bean或者又是一個FactoryBean
18         // 若是是FactoryBean,則建立Bean
19         // Now we have the bean instance, which may be a normal bean or a FactoryBean.
20         // If it's a FactoryBean, we use it to create a bean instance, unless the
21         // caller actually wants a reference to the factory.
22         // 若是beanInstance不是Factory或者beanName以&開頭,則直接返回
23         if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
24             return beanInstance;
25         }
26 
27         Object object = null;
28         // 若BeanDefinition爲null,則從緩存中加載bean對象
29         if (mbd == null) {
30             object = getCachedObjectForFactoryBean(beanName);
31         }
32         // 若是Object仍然爲空,則能夠確認beanInstance必定是FactoryBean。從而使用FactoryBean獲取Bean對象
33         // 經過beanInstance instanceof FactoryBean這裏判斷,若是beanInstance不是FactoryBean已經直接返回了
34         if (object == null) {
35             // Return bean instance from factory.
36             FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
37             // 檢測beanDefinitionMap中,也就是全部已加載的類中是否認義了beanName
38             // Caches object obtained from FactoryBean if it is a singleton.
39             if (mbd == null && containsBeanDefinition(beanName)) {
40                 // 將存儲XML配置文件的GenericBeanDefinition轉換爲RootBeanDefinition
41                 // 若是指定beanName是子Bean的話同時會合並父類的相關屬性
42                 mbd = getMergedLocalBeanDefinition(beanName);
43             }
44             // 是不是用戶定義的,而不是程序自己定義的
45             boolean synthetic = (mbd != null && mbd.isSynthetic());
46             // 核心函數,使用FactoryBean得到Bean對象
47             object = getObjectFromFactoryBean(factory, beanName, !synthetic);
48         }
49         return object;
50     }

分析:

  • 若是beanName以"&"開頭,表示是工廠類的實例對象,若是beanInstance爲NullBean則直接返回,若是beanInstance不爲FactoryBean,則拋出異常,這裏主要是校驗beanInstance的正確性
  • 若是beanInstance不是FactoryBean或者beanName不以"&"開頭,則直接返回beanInstance對象。這裏主要是對非FactoryBean的處理
  • 若是BeanDefinition爲null,則從緩存中加載bean對象,若是仍是爲null,則能夠肯定beanInstance必定是FactoryBean,具體看前面的兩個判斷
  • 檢測beanDefinitionMap中是否已經加載了該bean,若是加載過着會判斷是否須要合併父類的相關屬性--getMergedLocalBeanDefinition方法。
  • 最後使用getObjectFromFactoryBean獲取bean對象。

AbstractBeanFactory#getMergedLocalBeanDefinition

 1 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
 2         // Quick check on the concurrent map first, with minimal locking.
 3         // 快速從緩存中獲取,若是不爲null,則直接返回
 4         RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
 5         if (mbd != null) {
 6             return mbd;
 7         }
 8         // 獲取RootBeanDefinition,若是返回的BeanDefinition是子類的bean的話,則合併父類相關屬性
 9         // getBeanDefinition函數從beanDefinitionMap中取出對應的BeanDefinition
10         return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
11     }

分析:

  • 首先檢查緩存中是否存在已經轉換過的RootBeanDefinition對象,若是存在,則直接返回。
  • 經過getMergedBeanDefinition函數進行BeanDefinition的轉換。

AbstractBeanFactory#getMergedBeanDefinition

 1 protected RootBeanDefinition getMergedBeanDefinition(
 2             String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
 3             throws BeanDefinitionStoreException {
 4         // 作同步
 5         synchronized (this.mergedBeanDefinitions) {
 6             RootBeanDefinition mbd = null;
 7             // 若是containingBd爲null,則從mergedBeanDefinitions中嘗試獲取
 8             // Check with full lock now in order to enforce the same merged instance.
 9             if (containingBd == null) {
10                 mbd = this.mergedBeanDefinitions.get(beanName);
11             }
12             // 若是集合中不存在RootBeanDefinition
13             if (mbd == null) {
14                 // 而且無父類
15                 if (bd.getParentName() == null) {
16                     // 若是BeanDefinition是RootBeanDefinition類型,則直接拷貝
17                     // Use copy of given root bean definition.
18                     if (bd instanceof RootBeanDefinition) {
19                         mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
20                     } else {
21                         // 不然新建立一個RootBeanDefinition對象
22                         mbd = new RootBeanDefinition(bd);
23                     }
24                 } else {
25                     // 若是存在父類
26                     // Child bean definition: needs to be merged with parent.
27                     BeanDefinition pbd;
28                     try {
29                         // 首先獲取父類的beanName
30                         String parentBeanName = transformedBeanName(bd.getParentName());
31                         // beanName與父類beanName不相等
32                         if (!beanName.equals(parentBeanName)) {
33                             // 經過父類beanName返回BeanDefinition
34                             pbd = getMergedBeanDefinition(parentBeanName);
35                         } else {
36                             BeanFactory parent = getParentBeanFactory();
37                             if (parent instanceof ConfigurableBeanFactory) {
38                                 pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
39                             } else {
40                                 throw new NoSuchBeanDefinitionException(parentBeanName,
41                                                                         "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
42                                                                                 "': cannot be resolved without an AbstractBeanFactory parent");
43                             }
44                         }
45                     } catch (NoSuchBeanDefinitionException ex) {
46                         throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
47                                                                "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
48                     }
49                     // Deep copy with overridden values.
50                     mbd = new RootBeanDefinition(pbd);
51                     mbd.overrideFrom(bd);
52                 }
53 
54                 // Set default singleton scope, if not configured before.
55                 if (!StringUtils.hasLength(mbd.getScope())) {
56                     mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
57                 }
58 
59                 // A bean contained in a non-singleton bean cannot be a singleton itself.
60                 // Let's correct this on the fly here, since this might be the result of
61                 // parent-child merging for the outer bean, in which case the original inner bean
62                 // definition will not have inherited the merged outer bean's singleton status.
63                 if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
64                     mbd.setScope(containingBd.getScope());
65                 }
66 
67                 // Cache the merged bean definition for the time being
68                 // (it might still get re-merged later on in order to pick up metadata changes)
69                 if (containingBd == null && isCacheBeanMetadata()) {
70                     this.mergedBeanDefinitions.put(beanName, mbd);
71                 }
72             }
73 
74             return mbd;
75         }
76     }

分析(注意給方法是同步的,Spring中不少這種同步方法):

  • 首先從緩存中查找是否存在RootBeanDefinition,若是不存在,且當前BeanDefinition無父類,則會獲得一個RootBeanDefinition對象(若BeanDefinition自己就是RootBeanDefinition,則直接拷貝,不然就實例化一個對象)。
  • 若是BeanDefinition存在父類,且父類名beanName與子類beanName不相等,則經過父類去建立BeanDefinition對象(getMergedBeanDefinition),若是beanName不相等,則經過父類工廠去建立BeanDefinition對象。
  • RootBeanDefinition對象建立好後,會設置對象的做用域,若是以前爲設置,則默認爲單例模式(後續的做用域設置理解得不是很清楚),最後會緩存新生成的RootBeanDefinition對象。

FactoryBeanRegistrySupport#getObjectFromFactoryBean

 1 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
 2         // 爲單例模式,其緩存中存在該bean實例
 3         if (factory.isSingleton() && containsSingleton(beanName)) {
 4             /**
 5              * 作同步,內部其實使用的就是{@link DefaultSingletonBeanRegistry#singletonObjects}
 6              */
 7             synchronized (getSingletonMutex()) {
 8                 // 從緩存中獲取指定的factoryBean
 9                 Object object = this.factoryBeanObjectCache.get(beanName);
10                 if (object == null) {
11                     // 爲空,則從FactoryBean中獲取對象
12                     object = doGetObjectFromFactoryBean(factory, beanName);
13                     // Only post-process and store if not put there already during getObject() call above
14                     // (e.g. because of circular reference processing triggered by custom getBean calls)
15                     // 再次從緩存中獲取bean對象,主要是由於循環依賴
16                     Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
17                     if (alreadyThere != null) {
18                         object = alreadyThere;
19                     } else {
20                         // 須要後續處理
21                         if (shouldPostProcess) {
22                             // 若是該Bean處於建立中,則返回非處理對象,而不是存儲該對象
23                             if (isSingletonCurrentlyInCreation(beanName)) {
24                                 // Temporarily return non-post-processed object, not storing it yet..
25                                 return object;
26                             }
27                             // 單例bean的前置處理 用於添加標誌,當前bean正處於建立中
28                             beforeSingletonCreation(beanName);
29                             try {
30                                 // 對FactoryBean獲取的對象進行後置處理,返回生成的對象
31                                 object = postProcessObjectFromFactoryBean(object, beanName);
32                             } catch (Throwable ex) {
33                                 throw new BeanCreationException(beanName,
34                                                                 "Post-processing of FactoryBean's singleton object failed", ex);
35                             } finally {
36                                 // 單例bean的後置處理 和前置處理相反,前置添加,後置移除 移除標誌,當前bean不處於建立中
37                                 afterSingletonCreation(beanName);
38                             }
39                         }
40                         // 添加到factoryBeanObjectCache中進行緩存
41                         if (containsSingleton(beanName)) {
42                             this.factoryBeanObjectCache.put(beanName, object);
43                         }
44                     }
45                 }
46                 return object;
47             }
48         } else {
49             // 不知足第一個條件,不是單例,或者緩存中不存在,則從FactoryBean中獲取對象
50             Object object = doGetObjectFromFactoryBean(factory, beanName);
51             // 須要後續處理
52             if (shouldPostProcess) {
53                 try {
54                     // 對FactoryBean獲取的對象進行後處理
55                     // 返回生成的對象
56                     object = postProcessObjectFromFactoryBean(object, beanName);
57                 } catch (Throwable ex) {
58                     throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
59                 }
60             }
61             return object;
62         }
63     }

因爲篇幅緣由該函數將在後續文章中繼續分析,文章太長筆者認爲不宜閱讀。

總結

本文才進入加載bean的流程,從單例緩存中獲取單例bean對象,後續繼續強行開擼。


by Shawn Chen,2019.04.20,上午。

相關文章
相關標籤/搜索