前言:經過前幾篇文章的講解,我們已經得到了BeanDefinition,接下來将分析Bean的加載。
擷取Bean的入口:AbstractApplicationContext#getBean
1 public Object getBean(String name) throws BeansException {
2 // 檢測bean工廠是否存活
3 assertBeanFactoryActive();
4 return getBeanFactory().getBean(name);
5 }
分析:
首先檢查BeanFactory是否存活,還記得之前分析過的prepareRefresh()方法嗎?如果不記得了,請翻看之前的文章,那裡設定了active的值,然後在這裡做檢查。如果BeanFactory關閉,則抛出異常。
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 }
這裡的代碼稍微有點多,但是這段代碼非常重要,我們一步步來進行分析。
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 }
transformedBeanName函數的功能:傳回beanName,剝離工廠引用字首。
在BeanFactoryUtils#transformedBeanName中:
- 如果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 }
在加載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,上午。