【spring源码分析】IOC容器初始化(六)
前言:經過前幾篇文章的講解,我們已經得到了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,上午。
轉載于:https://www.cnblogs.com/developer_chan/p/10723911.html
總結
以上是生活随笔為你收集整理的【spring源码分析】IOC容器初始化(六)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小程序navigateBack,子页面传
- 下一篇: 承前祖德勤和俭下一句是什么啊?