前言:通過前幾篇文章的講解,咱們已經獲得了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 }
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
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
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對象。
注意這裏涉及到三個集合:
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中循環依賴的所在,具體流程:
若是從單例緩存中獲得bean對象,則會調用getObjectForBeanInstance方法進一步處理,由於從緩存中獲得的bean是最原始的bean,並不必定是最終所須要的bean對象。
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 }
分析:
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 }
分析:
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 }
分析:
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中不少這種同步方法):
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,上午。