Spring核心容器之Bean創(chuàng)建過程詳解
前言
獲取 Bean 的方法是 getBean,其來自 BeanFactory 繼承的 AbstractAutowireCapableBeanFactory 抽象類繼承的 AbstractBeanFactory 抽象類中。
1、整體流程
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { ... // 通過 beanName 獲取 Bean 實(shí)例 @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í)例時(shí)要使用的參數(shù) @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); } ... }
getBean 有多個(gè)重載方法,可分為通過 Bean 名稱或通過 Class 獲取 Bean 對(duì)象,這些重載方法底層都是調(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 會(huì)以“&”為前綴。這里會(huì)去掉該修飾符,并返回. * 2、如果是手動(dòng)注冊(cè)的別名,則將其解析為規(guī)范的名稱 */ final String beanName = transformedBeanName(name); Object bean; /** * 1、單例 Bean 在 Spring 的同一個(gè)容器內(nèi)只會(huì)被創(chuàng)建一次,后續(xù)再獲取 Bean,直接從單例緩存中獲取 * 2、這里先從單例 Bean 的緩存容器中,嘗試獲取目標(biāo) Bean * ( getSingleton 方法中存在解決單例 Bean 循環(huán)依賴問題的具體方案,這部分會(huì)在后面的章節(jié)詳細(xì)討論) */ 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、不論是單例還是原型的實(shí)例對(duì)象,最終都要通過 getObjectForBeanInstance 進(jìn)行轉(zhuǎn)換,最終得到的才是符合要求的bean實(shí)例。 // 2、有時(shí)候存在如 FactoryBean 這種并不是直接返回實(shí)例本身,而是返回指定方法返回的實(shí)例 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,則嘗試從父級(jí) 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ū)⒁獎(jiǎng)?chuàng)建),即將 beanName 加入 alreadyCreated 集合中 markBeanAsCreated(beanName); } try { // 通過 beanName 獲取對(duì)應(yīng)的 BeanDefinition,如果獲取 BeanDefinition 是子類 BeanDefinition, // 則通過與父級(jí)合并,返回目標(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) { // 若存在依賴則需要遞歸實(shí)例化依賴的 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 實(shí)例,根據(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 時(shí)指定的 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; }
整個(gè)方法的過程可以概括為:
- 解析 beanName
- 從單例 Bean 實(shí)例的緩存容器中,嘗試獲取目標(biāo) Bean ,若存在,則直接執(zhí)行最后一步,將 Bean 的類型轉(zhuǎn)換為 getBean 時(shí)指定的 requireType 類型,之后返回
- 若不存在,則進(jìn)入創(chuàng)建 Bean 實(shí)例的流程
- 如果當(dāng)前正在創(chuàng)建原型 Bean 實(shí)例,則處于循環(huán)依賴中,且原型 Bean 無法解決循環(huán)依賴,所以拋出異常
- 如果當(dāng)前 BeanFactory 中不存在目標(biāo) BeanDefinition,則從父 BeanFactory 獲取
- 獲取目標(biāo) BeanDefinition,如果獲取的 BeanDefinition 是子類 BeanDefinition(如 GenericBeanDefinition),則通過與父級(jí)合并,返回目標(biāo) bean 的 RootBeanDefinition
- 如果存在依賴的 Bean,則先實(shí)例化這些依賴的 Bean
- 依據(jù)當(dāng)前 Bean 的作用域,開始實(shí)例化 Bean ,單例或原型
- 判斷實(shí)例化的 Bean 是否是 FactoryBean 類型
- 將 Bean 的類型轉(zhuǎn)換為 getBean 時(shí)指定的 requireType 類型
- 最后返回 Bean 實(shí)例
以上就是 getBean 方法的大致流程,其中有兩個(gè)頻繁出現(xiàn)且非常重要的方法,一個(gè)是處理 FactoryBean 的 getObjectForBeanInstance方法,另一個(gè)是創(chuàng)建 Bean 的核心實(shí)現(xiàn) createBean 方法。
2、核心流程
2.1 解析 FactoryBean
關(guān)于 FactoryBean 在上一篇《Spring(七)核心容器 - 鉤子接口》文章中已經(jīng)討論過,F(xiàn)actoryBean 是 Spring 提供的鉤子接口,其屬于一種特殊的 Bean,不同于普通的 Bean,它是用來創(chuàng)建 Bean 實(shí)例的,屬于工廠 Bean,不過它和普通的創(chuàng)建不同,它提供了更為靈活的方式,一般用來創(chuàng)建那些創(chuàng)建過程比較復(fù)雜的 Bean。
而 FactoryBean 則是通過 getObjectForBeanlnstance 進(jìn)行解析。getObjectForBeanlnstance 是個(gè)高頻率使用的方法,無論是從緩存中獲得 bean 還是根據(jù)不同的 scope 策略加載bean??傊覀兊玫?bean 的實(shí)例后要做的第一步就是調(diào)用這個(gè)方法來檢測(cè)一下正確性,其實(shí)就是用于檢測(cè)當(dāng)前 bean 是否是 FactoryBean 類型的 bean ,如果是,那么需要調(diào)用該 bean 對(duì)應(yīng)的 FactoryBean 實(shí)例中的 getObject() 方法返回值作為真正返回的對(duì)象。
所以,當(dāng)我們 getBean 的時(shí)候,有兩種可能,一種是返回普通的 Bean,另一種是返回通過 getObjectForBeanInstance 方法解析 FactoryBean 返回的 Bean。
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // 如果 beanName 以“&”為前綴,但對(duì)應(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()); } } // 校驗(yàn)已獲取的 bean // 1、如果該 bean 不是 FactoryBean 類型,直接返回 // 2、如果是 FactoryBean 類型,且 beanName 以“&”為前綴,說明想獲取的是 FactoryBean ,也是直接返回 if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } // 從緩存中嘗試獲取 FactoryBean 創(chuàng)建的對(duì)象 Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // 到這里已確定 beanInstance 一定是 FactoryBean 類型,所以進(jìn)行強(qiáng)轉(zhuǎn) FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // 獲取 bean 對(duì)應(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; }
這個(gè)方法很簡單,大多是些輔助代碼以及一些功能性的判斷,真正的核心代碼在 getObjectFromFactoryBean 方法中。
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // 如果是單例 bean if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { // 嘗試從緩存中獲取,緩存中存儲(chǔ)的是已經(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 是否要進(jìn)行后置處理 ... 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; } }
接著進(jìn)入該方法中更為核心的 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)某個(gè) bean 的實(shí)例化過程比較復(fù)雜時(shí),可通過實(shí)現(xiàn) FactoryBean 接口,然后在重寫的 getObject 方法中定義實(shí)例化 bean 的邏輯,以后獲取該 bean 時(shí),會(huì)通過調(diào)用 getObject 方法進(jìn)行返回。值得注意的是 mybatis 底層就是通過 FactoryBean 來實(shí)現(xiàn)。
2.2 從 createBean 開始
接著進(jìn)入創(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); } // 對(duì) override 屬性進(jìn)行標(biāo)記和驗(yàn)證,本質(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ù)進(jìn)入 doCreateBean 方法中:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // BeanWrapper 包裝了 bean 對(duì)象,緩存了 bean 的內(nèi)省結(jié)果,并可以訪問 bean 的屬性、設(shè)置 bean 的屬性值 BeanWrapper instanceWrapper = null; // 如果是單例,嘗試獲取對(duì)應(yīng)的 BeanWrapper if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { /* * 說明對(duì)應(yīng)的bean還沒有創(chuàng)建,用對(duì)應(yīng)的策略(工廠方法、構(gòu)造函數(shù))創(chuàng)建 bean 實(shí)例,以及簡單初始化 * * 將 beanDefinition 轉(zhuǎn)成 BeanWrapper,大致流程如下: * 1. 如果存在工廠方法,則使用工廠方法初始化 * 2. 否則,如果存在多個(gè)構(gòu)造函數(shù),則根據(jù)參數(shù)確定構(gòu)造函數(shù),并利用構(gòu)造函數(shù)初始化 * 3. 否則,使用默認(rèn)構(gòu)造函數(shù)初始化 */ instanceWrapper = createBeanInstance(beanName, mbd, args); } // 從 BeanWrapper 中獲取包裝的 bean 實(shí)例 final Object bean = instanceWrapper.getWrappedInstance(); // 從 BeanWrapper 獲取包裝 bean 的 class 引用 Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // 執(zhí)行 MergedBeanDefinitionPostProcessor 后置處理器。 //(這里涉及一個(gè)極其重要的后置處理器實(shí)現(xiàn) AutowiredAnnotationBeanPostProcessor,其主要用來處理 @Autowired 注解,這部分會(huì)在后面詳細(xì)討論) synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } // catch... mbd.postProcessed = true; } } // 檢查是否需要提前曝光,避免循環(huán)依賴(循環(huán)依賴問題會(huì)在后面詳細(xì)討論) 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 { // 對(duì) bean 進(jìn)行填充,將各個(gè)屬性值注入,如果存在依賴的 bean 則進(jìn)行遞歸初始化 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 } } } } // 注冊(cè)DisposableBean try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } // catch... return exposedObject; }
該方法整體流程如下:
- 如果是單例,嘗試從緩存中獲取 bean 的包裝器 BeanWrapper,并清除緩存
- 如果不存在對(duì)應(yīng)的 Wrapper,則說明 bean 未被實(shí)例化,創(chuàng)建 bean 實(shí)例
- 執(zhí)行 MergedBeanDefinitionPostProcessor 后置處理器
- 檢查是否需要提前曝光,避免循環(huán)依賴
- 屬性填充,將所有屬性填充至bean 的實(shí)例中。
- 執(zhí)行一系列的初始化方法(回調(diào)鉤子接口)
- 再次檢查是否存在循環(huán)依賴
- 注冊(cè) DisposableBean
該過程中有幾個(gè)需要重點(diǎn)介紹的方法,分別是創(chuàng)建 Bean 實(shí)例的 createBeaninstance 方法、注入 Bean 屬性的 populateBean 方法以及執(zhí)行 Bean 初始化方法的 initializeBean 方法。
2.2.1 創(chuàng)建 Bean 實(shí)例
從 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 實(shí)例的回調(diào)方法 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } // 如果工廠方法不為空,則使用工廠方法進(jìn)行實(shí)例化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // 利用構(gòu)造函數(shù)進(jìn)行實(shí)例化,解析并確定目標(biāo)構(gòu)造函數(shù) boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { // 一個(gè)類可能有多個(gè)構(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 { // 使用默認(rèn)構(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); } // 使用默認(rèn)的構(gòu)造函數(shù) return instantiateBean(beanName, mbd); }
以上主要分為:
- 使用工廠方法進(jìn)行實(shí)例化
- 通過構(gòu)造函數(shù)實(shí)例化
不管是通過工廠方法還是構(gòu)造方法來實(shí)例化對(duì)象,到這里得到的也僅僅是一個(gè) bean 的最初實(shí)例,還不是我們最終期望的 bean,因?yàn)楹竺孢€需要對(duì) bean 實(shí)例進(jìn)行初始化處理,注入相應(yīng)的屬性值等。
2.2.2 初始化 Bean 實(shí)例 - 屬性注入
屬性注入通過 populateBean 方法實(shí)現(xiàn):
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 判斷實(shí)例化的 bean 是否為空 if (bw == null) { // 返回是否有為此 bean 定義的屬性值,如果有,則拋異常,提示 “無法將屬性值應(yīng)用于空實(shí)例” if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } // 沒有,則跳過屬性填充階段以獲取空實(shí)例 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 實(shí)例的屬性值集合 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ù)名稱自動(dòng)注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // 根據(jù)類型自動(dòng)注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } // 返回此工廠是否擁有 InstantiationAwareBeanPostProcessor boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 是否進(jìn)行依賴檢查 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; } } } } // 進(jìn)行依賴檢查 if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } if (pvs != null) { // 執(zhí)行屬性注入 applyPropertyValues(beanName, mbd, bw, pvs); } }
2.2.3 初始化 Bean 實(shí)例 - 執(zhí)行初始化方法(回調(diào)鉤子接口)
接著進(jìn)入 initializeBean 方法,在該方法中會(huì)回調(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 。這三個(gè)接口都屬于 Spring 的鉤子接口,是 Spring 開放出來的擴(kuò)展接口,可以影響 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); } // 這個(gè) BeanClassLoaderAware 接口傳遞的是 ClassLoader if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } // 這個(gè) BeanFactoryAware 接口傳遞的是 AbstractAutowireCapableBeanFactory if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
這里被回調(diào)的 Aware 接口有三個(gè),分別是 BeanNameAware 、BeanClassLoaderAware、BeanFactoryAware。
2、回調(diào) BeanPostProcessor 后置處理器的 postProcessBeforeInitialization 方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // getBeanPostProcessors 方法獲取所有的 BeanPostProcessor 后置處理器的實(shí)現(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; }
其中有一個(gè)后置處理器的實(shí)現(xiàn) ApplicationContextAwareProcessor ,其用來對(duì)剩余的 Aware 接口進(jìn)行回調(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 后置處理器的實(shí)現(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 實(shí)例的緩存容器中,嘗試獲取目標(biāo) Bean
- 緩存不存在則開始實(shí)例化 Bean ,區(qū)分單例或原型
- 實(shí)例化 Bean、初始化 Bean、執(zhí)行初始化方法及回調(diào)鉤子接口
- 判斷實(shí)例化的 Bean 是否是 FactoryBean 類型
到此這篇關(guān)于Spring核心容器之Bean創(chuàng)建過程詳解的文章就介紹到這了,更多相關(guān)Spring的Bean創(chuàng)建過程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java遞歸讀取文件例子_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
本文通過一段示例代碼給大家介紹了java遞歸讀取文件的方法,代碼簡單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-05-05java實(shí)現(xiàn)微信公眾號(hào)掃一掃
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信公眾號(hào)掃一掃,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Java基本知識(shí)點(diǎn)之變量和數(shù)據(jù)類型
這篇文章主要給大家介紹了關(guān)于Java基本知識(shí)點(diǎn)之變量和數(shù)據(jù)類型的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04