前言:在【spring源碼分析】IOC容器初始化(六)中分析了從單例緩存中加載bean對象,因爲篇幅緣由其核心函數html
FactoryBeanRegistrySupport#getObjectFromFactoryBean並未進行詳細分析,本文將繼續對bean加載過程的分析。spring
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 }
分析:緩存
函數分兩大分支:app
#1.單例且singletonObjects緩存中存在(該分支爲同步方法)ide
#2.不知足(#1)中的任何一條件
函數
在上述分析中涉及到幾個函數,下面一一進行分析。源碼分析
1 private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) 2 throws BeanCreationException { 3 4 Object object; 5 try { 6 // 若是權限不爲空 7 if (System.getSecurityManager() != null) { 8 AccessControlContext acc = getAccessControlContext(); 9 try { 10 // 從FactoryBean中獲取Bean對象[factory::getObject] 其實與else分支同樣的 11 object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); 12 } catch (PrivilegedActionException pae) { 13 throw pae.getException(); 14 } 15 } else { 16 // 若是權限爲空,則從Factory中獲取Bean對象 17 object = factory.getObject(); 18 } 19 } catch (FactoryBeanNotInitializedException ex) { 20 throw new BeanCurrentlyInCreationException(beanName, ex.toString()); 21 } catch (Throwable ex) { 22 throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); 23 } 24 25 // 進行一波校驗 26 // Do not accept a null value for a FactoryBean that's not fully 27 // initialized yet: Many FactoryBeans just return null then. 28 if (object == null) { 29 // 若是bean正在被建立,則拋出異常 30 if (isSingletonCurrentlyInCreation(beanName)) { 31 throw new BeanCurrentlyInCreationException( 32 beanName, "FactoryBean which is currently in creation returned null from getObject"); 33 } 34 object = new NullBean(); 35 } 36 return object; 37 }
分析:post
根據是否具備權限,經過FactoryBean#getObject獲取bean對象,若是bean對象爲null且正在被建立,則拋出異常,不然實例化一個NullBean對象進行返回。ui
1 /** 2 * 正在建立中的單例 Bean 的名字的集合 3 * Names of beans that are currently in creation. 4 */ 5 private final Set<String> singletonsCurrentlyInCreation = 6 Collections.newSetFromMap(new ConcurrentHashMap<>(16)); 7 8 public boolean isSingletonCurrentlyInCreation(String beanName) { 9 return this.singletonsCurrentlyInCreation.contains(beanName); 10 }
分析:this
該函數判斷bean是否正處於建立之中,該方法要與beforeSingletonCreation和afterSingletonCreation配合起來分析才能明白其重要性,他們記錄了bean的加載狀態,是檢查當前bean是否處於建立中的關鍵處,對解決bean的循環依賴起着重要做用。
1 protected void beforeSingletonCreation(String beanName) { 2 // 這裏會添加到正在建立bean的集合中 3 // 注意第一個條件,若是存在,則爲false,直接短路 4 // 只有當第一個條件不存在[false]時,纔會去進行添加操做 5 if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { 6 throw new BeanCurrentlyInCreationException(beanName); 7 } 8 }
分析:
注意這裏就會將正在建立的beanName添加到singletonsCurrentlyInCreation集合中,第一個條件是判斷該bean是否不會被檢測。
1 protected void afterSingletonCreation(String beanName) { 2 if (!this.inCreationCheckExclusions.contains(beanName) 3 && !this.singletonsCurrentlyInCreation.remove(beanName)) { // 移除 4 // 若是移除失敗,則拋出IllegalStateException異常 5 throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); 6 } 7 }
分析:
afterSingletonCreation方法與beforeSingletonCreation方法的功能相反,用於將beanName移除正在建立的集合singletonsCurrentlyInCreation,代表bean建立完成。
該方法的默認實現,就是返回當前bean對象。
1 // FactoryBeanRegistrySupport 2 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException { 3 return object; 4 }
固然,子類能夠對該方法進行重寫。
1 // AbstractAutowireCapableBeanFactory 2 3 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) { 4 return applyBeanPostProcessorsAfterInitialization(object, beanName); 5 } 6 7 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 8 throws BeansException { 9 10 Object result = existingBean; 11 // 遍歷BeanPostProcessor 12 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { 13 // 進行處理 14 // TODO: 2019/4/2 具體處理過程需詳細查看,這裏先走大流程 15 Object current = beanProcessor.postProcessAfterInitialization(result, beanName); 16 // 返回爲空,則返回傳入的Object對象 17 if (current == null) { 18 return result; 19 } 20 // 修改result 21 result = current; 22 } 23 return result; 24 }
分析:
這裏主要是遍歷BeanPostProcessor,而後對bean對象進行處理,關於後置處理器的分析後面再作分析。
到這裏從單例緩存中獲取bean對象的相應源碼已分析完成,接下來看單例緩存中無bean對象時,Spring的處理流程,再次將getBean的切入點代碼貼出來。
1 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, 2 @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { 3 4 // .........省略從單例緩存中獲取bean對象的代碼 5 } else { 6 // Fail if we're already creating this bean instance: 7 // We're assumably within a circular reference. 8 // Spring只能解決單例模式下的循環依賴,在原型模式下若是存在循環依賴則拋出異常 9 // 這裏檢測原型模式下,該bean是否在加載,若是在加載則拋出異常 10 if (isPrototypeCurrentlyInCreation(beanName)) { 11 throw new BeanCurrentlyInCreationException(beanName); 12 } 13 14 // 若是當前容器中沒有找到,則從父類容器中加載 15 // Check if bean definition exists in this factory. 16 BeanFactory parentBeanFactory = getParentBeanFactory(); 17 /** 18 * 調用{@link DefaultListableBeanFactory#containsBeanDefinition(String)}方法 19 * 其實就是在beanDefinitionMap中判斷是否存在beanName對應的BeanDefinition 20 */ 21 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 22 // Not found -> check parent. 23 // 肯定原始的beanName 24 String nameToLookup = originalBeanName(name); 25 // 若是父類容器爲AbstractBeanFactory,則委託父類處理 26 if (parentBeanFactory instanceof AbstractBeanFactory) { 27 return ((AbstractBeanFactory) parentBeanFactory).doGetBean( 28 nameToLookup, requiredType, args, typeCheckOnly); 29 } else if (args != null) { // 用明確的args從parentBeanFactory中,獲取Bean對象 30 // Delegation to parent with explicit args. 31 // 委託給父類構造函數getBean()處理 32 return (T) parentBeanFactory.getBean(nameToLookup, args); 33 } else if (requiredType != null) { // 用明確的requiredType從parentBeanFactory中,獲取Bean對象 34 // No args -> delegate to standard getBean method. 35 // 沒有args,委託給標準的getBean()處理 36 return parentBeanFactory.getBean(nameToLookup, requiredType); 37 } else { 38 // 直接使用nameToLookup從parentBeanFactory中獲取Bean對象 39 return (T) parentBeanFactory.getBean(nameToLookup); 40 } 41 } 42 43 // 若是不只僅是作類型檢查,而是建立bean,這裏須要記錄 44 if (!typeCheckOnly) { 45 markBeanAsCreated(beanName); 46 } 47 48 try { 49 /** 50 * 從容器中獲取beanName對應的GenericBeanDefinition對象,並轉換成RootBeanDefinition對象 51 * GenericBeanDefinition的建立{@link BeanDefinitionReaderUtils#createBeanDefinition}方法 52 */ 53 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 54 // 檢查合併的BeanDefinition 55 checkMergedBeanDefinition(mbd, beanName, args); 56 57 // Guarantee initialization of beans that the current bean depends on. 58 // 處理所依賴的bean 59 String[] dependsOn = mbd.getDependsOn(); 60 if (dependsOn != null) { 61 for (String dep : dependsOn) { 62 // 若給定的依賴bean已經註冊爲依賴給定的bean 63 // 即循環依賴狀況,拋出BeanCreationException異常 64 if (isDependent(beanName, dep)) { 65 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 66 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); 67 } 68 // 緩存依賴調用 69 registerDependentBean(dep, beanName); 70 try { 71 // 遞歸處理依賴 Bean 72 getBean(dep); 73 } catch (NoSuchBeanDefinitionException ex) { 74 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 75 "'" + beanName + "' depends on missing bean '" + dep + "'", ex); 76 } 77 } 78 } 79 // bean實例化 80 // Create bean instance. 81 // 單例模式 82 /** 83 * 這裏有個已建立bean的重要方法createBean 84 * {@link AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])} 85 */ 86 if (mbd.isSingleton()) { 87 sharedInstance = getSingleton(beanName, () -> { 88 try { 89 return createBean(beanName, mbd, args); 90 } catch (BeansException ex) { 91 // Explicitly remove instance from singleton cache: It might have been put there 92 // eagerly by the creation process, to allow for circular reference resolution. 93 // Also remove any beans that received a temporary reference to the bean. 94 // 顯式從單例緩存中刪除Bean實例 95 // 由於單例模式下爲了解決循環依賴,可能它已經存在,因此銷燬它 96 destroySingleton(beanName); 97 throw ex; 98 } 99 }); 100 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 101 } else if (mbd.isPrototype()) { // 原型模式 102 // It's a prototype -> create a new instance. 103 Object prototypeInstance = null; 104 try { 105 // 前置處理 106 beforePrototypeCreation(beanName); 107 /** 108 * 建立bean {@link AbstractAutowireCapableBeanFactory#createBean} 109 */ 110 prototypeInstance = createBean(beanName, mbd, args); 111 } finally { 112 /** 113 * 後置處理 與前置處理相反從{@link prototypesCurrentlyInCreation}中移除 114 */ 115 afterPrototypeCreation(beanName); 116 } 117 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 118 } else { //其餘做用域 119 // 得到scopeName對應的Scope對象 120 String scopeName = mbd.getScope(); 121 final Scope scope = this.scopes.get(scopeName); 122 if (scope == null) { 123 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 124 } 125 try { 126 /** 127 * 從指定的scope下建立bean 128 * {@link SimpleThreadScope#get方法} 129 */ 130 Object scopedInstance = scope.get(beanName, () -> { 131 beforePrototypeCreation(beanName); 132 try { 133 return createBean(beanName, mbd, args); 134 } finally { 135 afterPrototypeCreation(beanName); 136 } 137 }); 138 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 139 } catch (IllegalStateException ex) { 140 throw new BeanCreationException(beanName, 141 "Scope '" + scopeName + "' is not active for the current thread; consider " + 142 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 143 ex); 144 } 145 } 146 } catch (BeansException ex) { 147 cleanupAfterBeanCreationFailure(beanName); 148 throw ex; 149 } 150 } 151 152 // 檢查須要的類型是否符合bean的實際類型 153 // Check if required type matches the type of the actual bean instance. 154 if (requiredType != null && !requiredType.isInstance(bean)) { 155 try { 156 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); 157 if (convertedBean == null) { 158 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 159 } 160 return convertedBean; 161 } catch (TypeMismatchException ex) { 162 if (logger.isTraceEnabled()) { 163 logger.trace("Failed to convert bean '" + name + "' to required type '" + 164 ClassUtils.getQualifiedName(requiredType) + "'", ex); 165 } 166 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 167 } 168 } 169 return (T) bean; 170 }
分析:
#1.首先經過AbstractBeanFactory#isPrototypeCurrentlyInCreation檢查bean對象是否處於原型模式下的循環依賴,由於Spring只能解決單例模式下的循環依賴,若是在原型模式下也存在該bean對象,則會拋出異常。
1 // AbstractBeanFactory 2 /** 3 * 原型模式下存儲beanName的ThreadLocal<br/> 4 * Names of beans that are currently in creation. 5 */ 6 private final ThreadLocal<Object> prototypesCurrentlyInCreation = 7 new NamedThreadLocal<>("Prototype beans currently in creation"); 8 protected boolean isPrototypeCurrentlyInCreation(String beanName) { 9 Object curVal = this.prototypesCurrentlyInCreation.get(); 10 return (curVal != null && 11 (curVal.equals(beanName) //相等 12 || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName)))); // 包含 13 }
#2.AbstractBeanFactory#getParentBeanFactory檢查其父類BeanFactory是否存在,若是存在且beanDefinitionMap中不存在該BeanDefinition,則委託其父類經過getBean方法獲取bean對象。注意這裏首先會經過originalBeanName方法獲取原始beanName。
1 // AbstractBeanFactory 2 protected String originalBeanName(String name) { 3 String beanName = transformedBeanName(name); 4 if (name.startsWith(FACTORY_BEAN_PREFIX)) { 5 // 若是beanName以&開頭,則在加上&進行返回 由於transformedBeanName中會去掉& 6 beanName = FACTORY_BEAN_PREFIX + beanName; 7 } 8 return beanName; 9 }
#3.判斷bean是否須要作類型檢查,若是不只僅作類型檢查,則須要調用markBeanAsCreated函數進行記錄。
1 // AbstractBeanFactory 2 /** 3 * 已建立Bean的名字集合<br/> 4 * Names of beans that have already been created at least once. 5 */ 6 private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256)); 7 8 9 protected void markBeanAsCreated(String beanName) { 10 // 沒有建立 11 if (!this.alreadyCreated.contains(beanName)) { 12 // 作同步 13 synchronized (this.mergedBeanDefinitions) { 14 // 再次進行檢查,DoubleCheck模式 15 if (!this.alreadyCreated.contains(beanName)) { 16 // Let the bean definition get re-merged now that we're actually creating 17 // the bean... just in case some of its metadata changed in the meantime. 18 // 從mergedBeanDefinitions中刪除beanName,並在下次訪問時從新建立它 19 clearMergedBeanDefinition(beanName); 20 // 添加到已建立bean集合中 21 this.alreadyCreated.add(beanName); 22 } 23 } 24 } 25 }
#4. 接下來將對BeanDefinition進行轉換,由於最開始建立的BeanDefinition類型爲GenericBeanDefinition,getMergedLocalBeanDefinition方法在前面已經進行了分析,這裏不在贅述。
#5.調用checkMergedBeanDefinition對轉換後的RootBeanDefinition,若是RootBeanDefinition仍爲抽象的,則拋出異常,這裏抽象的對象還不能進行實例化。代碼以下:
1 // AbstractBeanFactory 2 protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args) 3 throws BeanDefinitionStoreException { 4 5 if (mbd.isAbstract()) { 6 throw new BeanIsAbstractException(beanName); 7 } 8 }
#6.處理依賴,若是在加載bean對象時,發現它有依賴bean的話,那麼在初始化該bean的時候須要先初始化依賴的bean對象
1 // 處理所依賴的bean 2 String[] dependsOn = mbd.getDependsOn(); 3 if (dependsOn != null) { 4 for (String dep : dependsOn) { 5 // 若給定的依賴bean已經註冊爲依賴給定的bean 6 // 即循環依賴狀況,拋出BeanCreationException異常 7 if (isDependent(beanName, dep)) { 8 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 9 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); 10 } 11 // 緩存依賴調用 12 registerDependentBean(dep, beanName); 13 try { 14 // 遞歸處理依賴 Bean 15 getBean(dep); 16 } catch (NoSuchBeanDefinitionException ex) { 17 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 18 "'" + beanName + "' depends on missing bean '" + dep + "'", ex); 19 } 20 } 21 }
分析:
DefaultSingletonBeanRegistry#isDependent
1 protected boolean isDependent(String beanName, String dependentBeanName) { 2 synchronized (this.dependentBeanMap) { 3 return isDependent(beanName, dependentBeanName, null); 4 } 5 } 6 private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) { 7 // alreadySeen 已經檢測的依賴bean 8 if (alreadySeen != null && alreadySeen.contains(beanName)) { 9 return false; 10 } 11 // 獲取原始的beanName 12 String canonicalName = canonicalName(beanName); 13 // 獲取當前beanName的依賴集合 14 Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName); 15 // 不存在,則說明不存在註冊依賴 16 if (dependentBeans == null) { 17 return false; 18 } 19 // 存在,則證實已經存在註冊依賴 20 if (dependentBeans.contains(dependentBeanName)) { 21 return true; 22 } 23 // 遞歸檢測依賴 24 for (String transitiveDependency : dependentBeans) { 25 if (alreadySeen == null) { 26 alreadySeen = new HashSet<>(); 27 } 28 // 添加到alreadySeen 29 alreadySeen.add(beanName); 30 // 遞推 31 if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { 32 return true; 33 } 34 } 35 return false; 36 }
分析:
這裏經過一些列判斷,是否依賴的bean是否已經注入,若是注入則返回true,不然返回false。
#7.若是依賴檢測經過,則調用registerDependentBean對依賴bean進行注入。
1 // DefaultSingletonBeanRegistry 2 3 /** 4 * 保存的是依賴beanName 映射關係:beanName --> 依賴beanName的集合<br/> 5 * Map between dependent bean names: bean name to Set of dependent bean names. 6 */ 7 private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64); 8 9 /** 10 * 保存的是依賴 beanName 之間的映射關係:依賴 beanName - > beanName 的集合 11 * Map between depending bean names: bean name to Set of bean names for the bean's dependencies. 12 */ 13 private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64); 14 15 public void registerDependentBean(String beanName, String dependentBeanName) { 16 // 獲取beanName 17 String canonicalName = canonicalName(beanName); 18 19 // 作同步 添加<canonicalName,<dependentBeanName>>到dependentBeanMap中 20 synchronized (this.dependentBeanMap) { 21 Set<String> dependentBeans = 22 this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); 23 if (!dependentBeans.add(dependentBeanName)) { 24 return; 25 } 26 } 27 // 作同步 添加<canonicalName,<dependentBeanName>>到dependenciesForBeanMap中 28 synchronized (this.dependenciesForBeanMap) { 29 Set<String> dependenciesForBean = 30 this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8)); 31 dependenciesForBean.add(canonicalName); 32 } 33 }
分析:
這裏就是就是將依賴的beanName關係添加到dependentBeanMap、dependenciesForBeanMap集合中。
#8.最後經過getBean方法實例化依賴bean對象,該方法會在後面進行分析。
在通過單例緩存中獲取bean對象、從父類工廠中獲取bean對象、處理依賴bean這三步後,接下來來到對各類scope的bean的建立。首先是單例模式bean對象的建立,咱們知道singleton爲Spring的bean的默認做用域,固然除了singleton以外,還有prototype、request等其餘的scope。
#1.singleton的初始化代碼以下
1 // AbstractBeanFactory 2 3 if (mbd.isSingleton()) { 4 sharedInstance = getSingleton(beanName, () -> { 5 try { 6 return createBean(beanName, mbd, args); 7 } catch (BeansException ex) { 8 // Explicitly remove instance from singleton cache: It might have been put there 9 // eagerly by the creation process, to allow for circular reference resolution. 10 // Also remove any beans that received a temporary reference to the bean. 11 // 顯式從單例緩存中刪除Bean實例 12 // 由於單例模式下爲了解決循環依賴,可能它已經存在,因此銷燬它 13 destroySingleton(beanName); 14 throw ex; 15 } 16 }); 17 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 18 }
分析:
單例模式bean的初始化是從getSingleton方法開始,固然這裏還有一個重要的createBean方法,該方法咱們留在後面進行分析,首先來看getSingleton方法。
1 // DefaultSingletonBeanRegistry 2 3 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { 4 Assert.notNull(beanName, "Bean name must not be null"); 5 // 作同步 6 synchronized (this.singletonObjects) { 7 // 從緩存中檢查一遍 8 // 由於singlton模式其實已經複用了建立的bean,因此該步驟必須檢查 9 Object singletonObject = this.singletonObjects.get(beanName); 10 // 爲空,開始進行加載 11 if (singletonObject == null) { 12 if (this.singletonsCurrentlyInDestruction) { 13 throw new BeanCreationNotAllowedException(beanName, 14 "Singleton bean creation not allowed while singletons of this factory are in destruction " + 15 "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); 16 } 17 if (logger.isDebugEnabled()) { 18 logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); 19 } 20 // 加載前置處理 其實就是打一個標記 21 beforeSingletonCreation(beanName); 22 // 首先將新的newSingleton設置爲false 23 boolean newSingleton = false; 24 boolean recordSuppressedExceptions = (this.suppressedExceptions == null); 25 if (recordSuppressedExceptions) { 26 this.suppressedExceptions = new LinkedHashSet<>(); 27 } 28 try { 29 // 初始化bean 30 // 該過程實際上是調用createBean()方法 這裏是一個回調方法 31 singletonObject = singletonFactory.getObject(); 32 newSingleton = true; 33 } catch (IllegalStateException ex) { 34 // Has the singleton object implicitly appeared in the meantime -> 35 // if yes, proceed with it since the exception indicates that state. 36 singletonObject = this.singletonObjects.get(beanName); 37 if (singletonObject == null) { 38 throw ex; 39 } 40 } catch (BeanCreationException ex) { 41 if (recordSuppressedExceptions) { 42 for (Exception suppressedException : this.suppressedExceptions) { 43 ex.addRelatedCause(suppressedException); 44 } 45 } 46 throw ex; 47 } finally { 48 if (recordSuppressedExceptions) { 49 this.suppressedExceptions = null; 50 } 51 // 一堆異常處理後,進行後置處理 移除標誌 52 afterSingletonCreation(beanName); 53 } 54 // 新的bean 加入緩存中 55 if (newSingleton) { 56 addSingleton(beanName, singletonObject); 57 } 58 } 59 return singletonObject; 60 } 61 }
分析(該方法一樣爲同步方法):
該方法其實並未真正建立bean對象,獲取bean對象的核心點在於singletonObject = singletonFactory.getObject(),但該方法是由createBean回調產生的。這裏僅僅是作了一部分準備和預處理步驟:
DefaultSingletonBeanRegistry#addSingleton
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); 29 30 /** 31 * 存儲已經註冊的單例 進行緩存<br/> 32 * Set of registered singletons, containing the bean names in registration order. 33 */ 34 private final Set<String> registeredSingletons = new LinkedHashSet<>(256); 35 36 protected void addSingleton(String beanName, Object singletonObject) { 37 synchronized (this.singletonObjects) { 38 this.singletonObjects.put(beanName, singletonObject); 39 this.singletonFactories.remove(beanName); 40 this.earlySingletonObjects.remove(beanName); 41 this.registeredSingletons.add(beanName); 42 } 43 }
分析:
一個put、兩個remove、一個add。
#2.原型模式
1 if (mbd.isPrototype()) { // 原型模式 2 // It's a prototype -> create a new instance. 3 Object prototypeInstance = null; 4 try { 5 // 前置處理 6 beforePrototypeCreation(beanName); 7 /** 8 * 建立bean {@link AbstractAutowireCapableBeanFactory#createBean} 9 */ 10 prototypeInstance = createBean(beanName, mbd, args); 11 } finally { 12 /** 13 * 後置處理 與前置處理相反從{@link prototypesCurrentlyInCreation}中移除 14 */ 15 afterPrototypeCreation(beanName); 16 } 17 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 18 }
分析:
原型模式下bean的初始化很簡單,直接建立一個新Bean實例就能夠了。
AbstractBeanFactory#beforePrototypeCreation
1 /** 2 * 原型模式下存儲beanName的ThreadLocal<br/> 3 * Names of beans that are currently in creation. 4 */ 5 private final ThreadLocal<Object> prototypesCurrentlyInCreation = 6 new NamedThreadLocal<>("Prototype beans currently in creation"); 7 8 protected void beforePrototypeCreation(String beanName) { 9 // 從ThreadLocal中取出對象 10 Object curVal = this.prototypesCurrentlyInCreation.get(); 11 if (curVal == null) { 12 // 若是爲空,則設置值 13 this.prototypesCurrentlyInCreation.set(beanName); 14 } else if (curVal instanceof String) { 15 // 若是curVal爲String類型,則進行添加 16 Set<String> beanNameSet = new HashSet<>(2); 17 beanNameSet.add((String) curVal); 18 beanNameSet.add(beanName); 19 this.prototypesCurrentlyInCreation.set(beanNameSet); 20 } else { 21 // 不然將curVal轉換成set集合,添加beanName 22 Set<String> beanNameSet = (Set<String>) curVal; 23 beanNameSet.add(beanName); 24 } 25 }
分析:
這裏的前置處理就是將beanName加入ThreadLocal中,邏輯簡單。
AbstractBeanFactory#afterPrototypeCreation
1 protected void afterPrototypeCreation(String beanName) { 2 Object curVal = this.prototypesCurrentlyInCreation.get(); 3 if (curVal instanceof String) { 4 this.prototypesCurrentlyInCreation.remove(); 5 } else if (curVal instanceof Set) { 6 Set<String> beanNameSet = (Set<String>) curVal; 7 beanNameSet.remove(beanName); 8 if (beanNameSet.isEmpty()) { 9 this.prototypesCurrentlyInCreation.remove(); 10 } 11 } 12 }
分析:
後置處理與前置處理beforePrototypeCreation正好相反,將標記從ThreadLocal中移除。
#3.其餘做用域
1 // 得到scopeName對應的Scope對象 2 String scopeName = mbd.getScope(); 3 final Scope scope = this.scopes.get(scopeName); 4 if (scope == null) { 5 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 6 } 7 try { 8 /** 9 * 從指定的scope下建立bean 10 * {@link SimpleThreadScope#get方法} 11 */ 12 Object scopedInstance = scope.get(beanName, () -> { 13 beforePrototypeCreation(beanName); 14 try { 15 return createBean(beanName, mbd, args); 16 } finally { 17 afterPrototypeCreation(beanName); 18 } 19 }); 20 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 21 } catch (IllegalStateException ex) { 22 throw new BeanCreationException(beanName, 23 "Scope '" + scopeName + "' is not active for the current thread; consider " + 24 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 25 ex); 26 } 27 } 28 } catch (BeansException ex) { 29 cleanupAfterBeanCreationFailure(beanName); 30 throw ex; 31 }
分析:
其餘做用域bean的建立過程與原型模式的流程同樣,只是獲取bean的方式變成了Scope#get(String name,ObjectFactory<?> objectFactory)。
1 // SimpleThreadScope 2 public Object get(String name, ObjectFactory<?> objectFactory) { 3 // 獲取scope緩存 4 Map<String, Object> scope = this.threadScope.get(); 5 Object scopedObject = scope.get(name); 6 if (scopedObject == null) { 7 // 這裏getObject也是進行方法回調 8 scopedObject = objectFactory.getObject(); 9 // 加入緩存 10 scope.put(name, scopedObject); 11 } 12 return scopedObject; 13 }
這裏僅僅是Scope接口的一種實現,該接口還有其餘多種實現,其具體源碼可查看相應實現類:
至此,Bean加載的大體流程已分析完畢,固然本篇文章並未分析一個很重要的函數createBean,該函數留在後續的文章繼續分析。
by Shawn Chen,2019.04.22,下午。