Spring核心容器之Bean創(chuàng)建過程詳解
前言
獲取 Bean 的方法是 getBean,其來自 BeanFactory 繼承的 AbstractAutowireCapableBeanFactory 抽象類繼承的 AbstractBeanFactory 抽象類中。
1、整體流程
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { ... // 通過 beanName 獲取 Bean 實例 @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } // 檢索所需的 bean 類型 @Override public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } // 使用顯式參數(shù)創(chuàng)建 Bean 實例時要使用的參數(shù) @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); } ... }
getBean 有多個重載方法,可分為通過 Bean 名稱或通過 Class 獲取 Bean 對象,這些重載方法底層都是調(diào)用 doGetBean 方法。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { /** * 1、如果獲取的 Bean 類型是 FactoryBean,則參數(shù) name 會以“&”為前綴。這里會去掉該修飾符,并返回. * 2、如果是手動注冊的別名,則將其解析為規(guī)范的名稱 */ final String beanName = transformedBeanName(name); Object bean; /** * 1、單例 Bean 在 Spring 的同一個容器內(nèi)只會被創(chuàng)建一次,后續(xù)再獲取 Bean,直接從單例緩存中獲取 * 2、這里先從單例 Bean 的緩存容器中,嘗試獲取目標(biāo) Bean * ( getSingleton 方法中存在解決單例 Bean 循環(huán)依賴問題的具體方案,這部分會在后面的章節(jié)詳細討論) */ Object sharedInstance = getSingleton(beanName); // 如果存在目標(biāo) Bean if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { // 目標(biāo) Bean 是否正在被創(chuàng)建 if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } // 1、不論是單例還是原型的實例對象,最終都要通過 getObjectForBeanInstance 進行轉(zhuǎn)換,最終得到的才是符合要求的bean實例。 // 2、有時候存在如 FactoryBean 這種并不是直接返回實例本身,而是返回指定方法返回的實例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } // 如果不存在目標(biāo) Bean else { // 如果當(dāng)前正在創(chuàng)建原型 Bean,則處于循環(huán)依賴中,且原型 Bean 無法解決循環(huán)依賴,所以拋出異常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 如果 beanDefinitionMap 也就是容器中不存在目標(biāo) Bean,則嘗試從父級 beanFactory 中獲取 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // 獲取真正 beanName。如果獲取的 Bean 類型是 FactoryBean,則去掉 beanName 的修飾符“&” String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // 遞歸到 BeanFactory 中尋找 return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { // 將指定的 bean 標(biāo)記為已經(jīng)創(chuàng)建(或?qū)⒁獎?chuàng)建),即將 beanName 加入 alreadyCreated 集合中 markBeanAsCreated(beanName); } try { // 通過 beanName 獲取對應(yīng)的 BeanDefinition,如果獲取 BeanDefinition 是子類 BeanDefinition, // 則通過與父級合并,返回目標(biāo) bean 的 RootBeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 檢查bean是否是抽象的,如果是則拋出異常 checkMergedBeanDefinition(mbd, beanName, args); // 獲取目標(biāo) bean 所依賴的其它 bean 名稱 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { // 若存在依賴則需要遞歸實例化依賴的 bean for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } /* 開始創(chuàng)建目標(biāo) bean 實例,根據(jù) bean 的 scope 執(zhí)行不同的創(chuàng)建方式。單例,原型,其他的scope */ // 這是單例的 bean 創(chuàng)建方式 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { // 創(chuàng)建 Bean 的核心方法 return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // prototype 類型的 bean 創(chuàng)建方式 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } // 其它類型 else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // 將 Bean 的類型轉(zhuǎn)換為 getBean 時指定的 requireType 類型 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
整個方法的過程可以概括為:
- 解析 beanName
- 從單例 Bean 實例的緩存容器中,嘗試獲取目標(biāo) Bean ,若存在,則直接執(zhí)行最后一步,將 Bean 的類型轉(zhuǎn)換為 getBean 時指定的 requireType 類型,之后返回
- 若不存在,則進入創(chuàng)建 Bean 實例的流程
- 如果當(dāng)前正在創(chuàng)建原型 Bean 實例,則處于循環(huán)依賴中,且原型 Bean 無法解決循環(huán)依賴,所以拋出異常
- 如果當(dāng)前 BeanFactory 中不存在目標(biāo) BeanDefinition,則從父 BeanFactory 獲取
- 獲取目標(biāo) BeanDefinition,如果獲取的 BeanDefinition 是子類 BeanDefinition(如 GenericBeanDefinition),則通過與父級合并,返回目標(biāo) bean 的 RootBeanDefinition
- 如果存在依賴的 Bean,則先實例化這些依賴的 Bean
- 依據(jù)當(dāng)前 Bean 的作用域,開始實例化 Bean ,單例或原型
- 判斷實例化的 Bean 是否是 FactoryBean 類型
- 將 Bean 的類型轉(zhuǎn)換為 getBean 時指定的 requireType 類型
- 最后返回 Bean 實例
以上就是 getBean 方法的大致流程,其中有兩個頻繁出現(xiàn)且非常重要的方法,一個是處理 FactoryBean 的 getObjectForBeanInstance方法,另一個是創(chuàng)建 Bean 的核心實現(xiàn) createBean 方法。
2、核心流程
2.1 解析 FactoryBean
關(guān)于 FactoryBean 在上一篇《Spring(七)核心容器 - 鉤子接口》文章中已經(jīng)討論過,F(xiàn)actoryBean 是 Spring 提供的鉤子接口,其屬于一種特殊的 Bean,不同于普通的 Bean,它是用來創(chuàng)建 Bean 實例的,屬于工廠 Bean,不過它和普通的創(chuàng)建不同,它提供了更為靈活的方式,一般用來創(chuàng)建那些創(chuàng)建過程比較復(fù)雜的 Bean。
而 FactoryBean 則是通過 getObjectForBeanlnstance 進行解析。getObjectForBeanlnstance 是個高頻率使用的方法,無論是從緩存中獲得 bean 還是根據(jù)不同的 scope 策略加載bean??傊?,我們得到 bean 的實例后要做的第一步就是調(diào)用這個方法來檢測一下正確性,其實就是用于檢測當(dāng)前 bean 是否是 FactoryBean 類型的 bean ,如果是,那么需要調(diào)用該 bean 對應(yīng)的 FactoryBean 實例中的 getObject() 方法返回值作為真正返回的對象。
所以,當(dāng)我們 getBean 的時候,有兩種可能,一種是返回普通的 Bean,另一種是返回通過 getObjectForBeanInstance 方法解析 FactoryBean 返回的 Bean。
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // 如果 beanName 以“&”為前綴,但對應(yīng)的 bean 不是 FactoryBean 類型,則拋異常 if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } } // 校驗已獲取的 bean // 1、如果該 bean 不是 FactoryBean 類型,直接返回 // 2、如果是 FactoryBean 類型,且 beanName 以“&”為前綴,說明想獲取的是 FactoryBean ,也是直接返回 if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } // 從緩存中嘗試獲取 FactoryBean 創(chuàng)建的對象 Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // 到這里已確定 beanInstance 一定是 FactoryBean 類型,所以進行強轉(zhuǎn) FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // 獲取 bean 對應(yīng)的 BeanDefinition if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } // 當(dāng)前 bean 是否是用戶定義的,而不是應(yīng)用程序自己定義的 boolean synthetic = (mbd != null && mbd.isSynthetic()); // 解析 FactoryBean 的核心方法 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
這個方法很簡單,大多是些輔助代碼以及一些功能性的判斷,真正的核心代碼在 getObjectFromFactoryBean 方法中。
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // 如果是單例 bean if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // 嘗試從緩存中獲取,緩存中存儲的是已經(jīng)通過 FactoryBean 創(chuàng)建的 bean Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // 通過 FactoryBean 創(chuàng)建真正的 bean object = doGetObjectFromFactoryBean(factory, beanName); // 這里大概是 在執(zhí)行上一步 doGetObjectFromFactoryBean 方法過程中,該 bean 已被其它線程創(chuàng)建并緩存了起來 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { // 如果沒有 if (shouldPostProcess) { // Bean 是否要進行后置處理 ... try { // 執(zhí)行后置處理器(關(guān)于后置處理器已在上篇文章討論過) object = postProcessObjectFromFactoryBean(object, beanName); } // catch ... } ... } } return object; } } else { // 如果不是單例 bean // 通過 FactoryBean 創(chuàng)建真正的 bean Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { // 執(zhí)行后置處理器 object = postProcessObjectFromFactoryBean(object, beanName); } // catch ... } return object; } }
接著進入該方法中更為核心的 doGetObjectFromFactoryBean 方法:
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException { Object object; try { // try...catch... else { // 調(diào)用 FactoryBean 的 getObject 方法,返回真正的 bean object = factory.getObject(); } } // try...catch... ... return object; }
可以看到,最后調(diào)用的就是 FactoryBean.getObject 方法
public interface FactoryBean<T> { @Nullable T getObject() throws Exception; }
當(dāng)某個 bean 的實例化過程比較復(fù)雜時,可通過實現(xiàn) FactoryBean 接口,然后在重寫的 getObject 方法中定義實例化 bean 的邏輯,以后獲取該 bean 時,會通過調(diào)用 getObject 方法進行返回。值得注意的是 mybatis 底層就是通過 FactoryBean 來實現(xiàn)。
2.2 從 createBean 開始
接著進入創(chuàng)建 Bean 的下一步 createBean 方法:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // 根據(jù)設(shè)置的 class 屬性或 className 來解析得到 Class 引用 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // 對 override 屬性進行標(biāo)記和驗證,本質(zhì)上是處理 lookup-method 和 replaced-method 標(biāo)簽 try { mbdToUse.prepareMethodOverrides(); } // catch... try { // 執(zhí)行 BeanPostProcessors 后置處理器,如果有 bean 返回,則不執(zhí)行接下來創(chuàng)建 bean 的操作,直接返回該 bean Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } // catch... try { // 創(chuàng)建 Bean 的核心方法 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } // catch... }
繼續(xù)進入 doCreateBean 方法中:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // BeanWrapper 包裝了 bean 對象,緩存了 bean 的內(nèi)省結(jié)果,并可以訪問 bean 的屬性、設(shè)置 bean 的屬性值 BeanWrapper instanceWrapper = null; // 如果是單例,嘗試獲取對應(yīng)的 BeanWrapper if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { /* * 說明對應(yīng)的bean還沒有創(chuàng)建,用對應(yīng)的策略(工廠方法、構(gòu)造函數(shù))創(chuàng)建 bean 實例,以及簡單初始化 * * 將 beanDefinition 轉(zhuǎn)成 BeanWrapper,大致流程如下: * 1. 如果存在工廠方法,則使用工廠方法初始化 * 2. 否則,如果存在多個構(gòu)造函數(shù),則根據(jù)參數(shù)確定構(gòu)造函數(shù),并利用構(gòu)造函數(shù)初始化 * 3. 否則,使用默認構(gòu)造函數(shù)初始化 */ instanceWrapper = createBeanInstance(beanName, mbd, args); } // 從 BeanWrapper 中獲取包裝的 bean 實例 final Object bean = instanceWrapper.getWrappedInstance(); // 從 BeanWrapper 獲取包裝 bean 的 class 引用 Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // 執(zhí)行 MergedBeanDefinitionPostProcessor 后置處理器。 //(這里涉及一個極其重要的后置處理器實現(xiàn) AutowiredAnnotationBeanPostProcessor,其主要用來處理 @Autowired 注解,這部分會在后面詳細討論) synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } // catch... mbd.postProcessed = true; } } // 檢查是否需要提前曝光,避免循環(huán)依賴(循環(huán)依賴問題會在后面詳細討論) boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // 開始初始化 bean Object exposedObject = bean; try { // 對 bean 進行填充,將各個屬性值注入,如果存在依賴的 bean 則進行遞歸初始化 populateBean(beanName, mbd, instanceWrapper); // 執(zhí)行一系列的初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } // catch... // 再次檢查是否循環(huán)依賴 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { // throw } } } } // 注冊DisposableBean try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } // catch... return exposedObject; }
該方法整體流程如下:
- 如果是單例,嘗試從緩存中獲取 bean 的包裝器 BeanWrapper,并清除緩存
- 如果不存在對應(yīng)的 Wrapper,則說明 bean 未被實例化,創(chuàng)建 bean 實例
- 執(zhí)行 MergedBeanDefinitionPostProcessor 后置處理器
- 檢查是否需要提前曝光,避免循環(huán)依賴
- 屬性填充,將所有屬性填充至bean 的實例中。
- 執(zhí)行一系列的初始化方法(回調(diào)鉤子接口)
- 再次檢查是否存在循環(huán)依賴
- 注冊 DisposableBean
該過程中有幾個需要重點介紹的方法,分別是創(chuàng)建 Bean 實例的 createBeaninstance 方法、注入 Bean 屬性的 populateBean 方法以及執(zhí)行 Bean 初始化方法的 initializeBean 方法。
2.2.1 創(chuàng)建 Bean 實例
從 createBeaninstance 開始:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } // 如果有用于創(chuàng)建 bean 實例的回調(diào)方法 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } // 如果工廠方法不為空,則使用工廠方法進行實例化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // 利用構(gòu)造函數(shù)進行實例化,解析并確定目標(biāo)構(gòu)造函數(shù) boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { // 一個類可能有多個構(gòu)造函數(shù),需要根據(jù)參數(shù)來確定具體的構(gòu)造函數(shù) if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } // 如果已經(jīng)解析過,則使用已經(jīng)確定的構(gòu)造方法 if (resolved) { if (autowireNecessary) { // 依據(jù)構(gòu)造函數(shù)注入 return autowireConstructor(beanName, mbd, null, null); } else { // 使用默認構(gòu)造函數(shù)構(gòu)造 return instantiateBean(beanName, mbd); } } // 根據(jù)參數(shù)確定構(gòu)造函數(shù) Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // 使用默認的構(gòu)造函數(shù) return instantiateBean(beanName, mbd); }
以上主要分為:
- 使用工廠方法進行實例化
- 通過構(gòu)造函數(shù)實例化
不管是通過工廠方法還是構(gòu)造方法來實例化對象,到這里得到的也僅僅是一個 bean 的最初實例,還不是我們最終期望的 bean,因為后面還需要對 bean 實例進行初始化處理,注入相應(yīng)的屬性值等。
2.2.2 初始化 Bean 實例 - 屬性注入
屬性注入通過 populateBean 方法實現(xiàn):
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 判斷實例化的 bean 是否為空 if (bw == null) { // 返回是否有為此 bean 定義的屬性值,如果有,則拋異常,提示 “無法將屬性值應(yīng)用于空實例” if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } // 沒有,則跳過屬性填充階段以獲取空實例 else { // Skip property population phase for null instance. return; } } // 在設(shè)置屬性之前,先執(zhí)行 InstantiationAwareBeanPostProcessors 后置處理器,這些后置處理器可以用其它方式注入屬性,如字段注入。 boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } // 當(dāng)使用了 InstantiationAwareBeanPostProcessors 后置處理器注入屬性,則結(jié)束屬性注入流程,直接返回 if (!continueWithPropertyPopulation) { return; } // 獲取 bean 實例的屬性值集合 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // 根據(jù)名稱自動注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // 根據(jù)類型自動注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } // 返回此工廠是否擁有 InstantiationAwareBeanPostProcessor boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 是否進行依賴檢查 boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); // 在屬性注入前執(zhí)行 InstantiationAwareBeanPostProcessor 后置處理器 if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } // 進行依賴檢查 if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } if (pvs != null) { // 執(zhí)行屬性注入 applyPropertyValues(beanName, mbd, bw, pvs); } }
2.2.3 初始化 Bean 實例 - 執(zhí)行初始化方法(回調(diào)鉤子接口)
接著進入 initializeBean 方法,在該方法中會回調(diào)許多在 Bean 初始化階段執(zhí)行的方法。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // 回調(diào) Aware 系列接口 if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } // 回調(diào) BeanPostProcessor 后置處理器的 postProcessBeforeInitialization 方法 Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 回調(diào) InitializingBean 的 afterPropertiesSet 方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 回調(diào) BeanPostProcessor 后置處理器的 postProcessAfterInitialization 方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
可以看到,在 Bean 的初始化階段,分別回調(diào)了 Aware 系列接口、BeanPostProcessor 后置處理器、InitializingBean 。這三個接口都屬于 Spring 的鉤子接口,是 Spring 開放出來的擴展接口,可以影響 Bean 的生命周期。
Bean 的初始化階段
1、回調(diào) Aware 系列接口
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { // 如果當(dāng)前 Bean 繼承了 BeanNameAware 接口,則回調(diào)接口中的 setBeanName 方法,并傳遞 beanName 參數(shù) if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } // 這個 BeanClassLoaderAware 接口傳遞的是 ClassLoader if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } // 這個 BeanFactoryAware 接口傳遞的是 AbstractAutowireCapableBeanFactory if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
這里被回調(diào)的 Aware 接口有三個,分別是 BeanNameAware 、BeanClassLoaderAware、BeanFactoryAware。
2、回調(diào) BeanPostProcessor 后置處理器的 postProcessBeforeInitialization 方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // getBeanPostProcessors 方法獲取所有的 BeanPostProcessor 后置處理器的實現(xiàn),并循環(huán)執(zhí)行 postProcessBeforeInitialization 方法,參數(shù)是當(dāng)前 Bean 以及 beanName 。 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
其中有一個后置處理器的實現(xiàn) ApplicationContextAwareProcessor ,其用來對剩余的 Aware 接口進行回調(diào):
@Override public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { AccessControlContext acc = null; //... invokeAwareInterfaces(bean); //... return bean; }
private void invokeAwareInterfaces(Object bean) { if (bean instanceof Aware) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } } }
3、回調(diào) InitializingBean 的 afterPropertiesSet 方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { //.. ((InitializingBean) bean).afterPropertiesSet(); //.. }
4、回調(diào) BeanPostProcessor 后置處理器的 postProcessAfterInitialization 方法
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // getBeanPostProcessors 方法獲取所有的 BeanPostProcessor 后置處理器的實現(xiàn),并循環(huán)執(zhí)行 postProcessAfterInitialization 方法,參數(shù)是當(dāng)前 Bean 以及 beanName 。 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
到這里,創(chuàng)建 Bean 的核心流程就討論結(jié)束,可歸納為:
- 解析 beanName
- 從單例 Bean 實例的緩存容器中,嘗試獲取目標(biāo) Bean
- 緩存不存在則開始實例化 Bean ,區(qū)分單例或原型
- 實例化 Bean、初始化 Bean、執(zhí)行初始化方法及回調(diào)鉤子接口
- 判斷實例化的 Bean 是否是 FactoryBean 類型
到此這篇關(guān)于Spring核心容器之Bean創(chuàng)建過程詳解的文章就介紹到這了,更多相關(guān)Spring的Bean創(chuàng)建過程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java遞歸讀取文件例子_動力節(jié)點Java學(xué)院整理
本文通過一段示例代碼給大家介紹了java遞歸讀取文件的方法,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2017-05-05