該系列文章是本人在學習 Spring 的過程當中總結下來的,裏面涉及到相關源碼,可能對讀者不太友好,請結合個人源碼註釋 Spring 源碼分析 GitHub 地址 進行閱讀html
Spring 版本:5.1.14.RELEASEjava
開始閱讀這一系列文章以前,建議先查看《深刻了解 Spring IoC(面試題)》這一篇文章git
該系列其餘文章請查看:《死磕 Spring 之 IoC 篇 - 文章導讀》github
上一篇《開啓 Bean 的加載》文章分析了 Bean 的整個加載過程,當咱們顯示或者隱式地調用AbstractBeanFactory
的 getBean(...)
方法時,會觸發 Bean 的加載,會進行一系列的處理,具體實現可查看上一篇文章。面試
對於不一樣做用域的 Bean,底層都會調用 AbstractAutowireCapableBeanFactory
的 createBean(...)
方法進行建立,建立 Bean 的過程涉及到 Bean 生命週期的大部分階段,例如實例化階段、屬性賦值階段、Aware 接口回調階段、初始化階段都是在這個方法中完成的,這個核心方法在上一篇文章沒有講述,接下來將在本文進行分析。spring
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
抽象類,繼承 AbstractBeanFactory,實現 AutowireCapableBeanFactory 接口,完成 Bean 的建立express
createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法,建立 Bean,方法以下:緩存
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. // <1> 獲取 `mbd` 對應的 Class 對象,確保當前 Bean 可以被建立出來 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); // 若是這裏獲取到了 Class 對象,可是 `mbd` 中沒有 Class 對象的相關信息,表示這個 Class 對象是動態解析出來的 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { // 複製一份 `mbd`,並設置 Class 對象,由於動態解析出來的 Class 對象不被共享 mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { // <2> 對全部的 MethodOverride 進行驗證和準備工做(確保存在對應的方法,並設置爲不能重複加載) mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. /** * <3> 在實例化前進行相關處理,會先調用全部 {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} * 注意,若是這裏返回對象不是 `null` 的話,不會繼續往下執行本來初始化操做,直接返回,也就是說這個方法返回的是最終實例對象 * 能夠經過這種方式提早返回一個代理對象,例如 AOP 的實現,或者 RPC 遠程調用的實現(由於本地類沒有遠程能力,能夠經過這種方式進行攔截) */ Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { // <4> 建立 Bean 對象 `beanInstance`,若是上一步沒有返回代理對象,就只能走常規的路線進行 Bean 的建立了 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } // <5> 將 `beanInstance` 返回 return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
入參:安全
beanName
:Bean 的名稱mbd
:Bean 的 BeanDefinition 對象(合併後)args
:建立 Bean 的參數,咱們一般不會傳,因此這裏爲 null
過程大體以下:app
獲取 mbd
對應的 Class 對象,確保當前 Bean 可以被建立出來,調用 resolveBeanClass(...)
方法
對全部的 MethodOverride 進行驗證和準備工做(確保存在對應的方法,並設置爲不能重複加載)
實例化前階段在實例化前進行相關處理,會先調用全部 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
注意,若是這裏返回對象不是 null
的話,不會繼續往下執行本來初始化操做,直接返回,也就是說這個方法返回的是最終實例對象
能夠經過這種方式提早返回一個代理對象,例如 AOP 的實現,或者 RPC 遠程調用的實現(由於本地類沒有遠程能力,能夠經過這種方式進行攔截)
建立 Bean 對象 beanInstance
,若是上一步沒有返回代理對象,就只能走常規的路線進行 Bean 的建立了,調用 doCreateBean(...)
方法
將 beanInstance
返回
能夠看到這個方法中並無開始真正 Bean 的建立,在這個方法的第 4
步會調用 doCreateBean(...)
方法建立 Bean
doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
,建立 Bean,方法以下:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. /** * <1> Bean 的實例化階段,會將 Bean 的實例對象封裝成 {@link BeanWrapperImpl} 包裝對象 * BeanWrapperImpl 承擔的角色: * 1. Bean 實例的包裝 * 2. {@link org.springframework.beans.PropertyAccessor} 屬性編輯器 * 3. {@link org.springframework.beans.PropertyEditorRegistry} 屬性編輯器註冊表 * 4. {@link org.springframework.core.convert.ConversionService} 類型轉換器(Spring 3+,替換了以前的 TypeConverter) */ BeanWrapper instanceWrapper = null; // <1.1> 若是是單例模式,則先嚐試從 `factoryBeanInstanceCache` 緩存中獲取實例對象,並從緩存中移除 if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } // <1.2> 使用合適的實例化策略來建立 Bean 的實例:工廠方法、構造函數自動注入、簡單初始化 // 主要是將 BeanDefinition 轉換爲 BeanWrapper 對象 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } // <1.3> 獲取包裝的實例對象 `bean` final Object bean = instanceWrapper.getWrappedInstance(); // <1.4> 獲取包裝的實例對象的類型 `beanType` Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. // <2> 對 RootBeanDefinition(合併後)進行加工處理 synchronized (mbd.postProcessingLock) { // 加鎖,線程安全 // <2.1> 若是該 RootBeanDefinition 沒有處理過,則進行下面的處理 if (!mbd.postProcessed) { try { /** * <2.2> 對 RootBeanDefinition(合併後)進行加工處理 * 調用全部 {@link MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition} * 【重要】例若有下面兩個處理器: * 1. AutowiredAnnotationBeanPostProcessor 會先解析出 @Autowired 和 @Value 註解標註的屬性的注入元信息,後續進行依賴注入; * 2. CommonAnnotationBeanPostProcessor 會先解析出 @Resource 註解標註的屬性的注入元信息,後續進行依賴注入, * 它也會找到 @PostConstruct 和 @PreDestroy 註解標註的方法,並構建一個 LifecycleMetadata 對象,用於後續生命週期中的初始化和銷燬 */ applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } // <2.3> 設置該 RootBeanDefinition 被處理過,避免重複處理 mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. // <3> 提早暴露這個 `bean`,若是能夠的話,目的是解決單例模式 Bean 的循環依賴注入 // <3.1> 判斷是否能夠提早暴露 boolean earlySingletonExposure = (mbd.isSingleton() // 單例模式 && this.allowCircularReferences // 容許循環依賴,默認爲 true && isSingletonCurrentlyInCreation(beanName)); // 當前單例 bean 正在被建立,在前面已經標記過 if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } /** * <3.2> * 建立一個 ObjectFactory 實現類,用於返回當前正在被建立的 `bean`,提早暴露,保存在 `singletonFactories` (**三級 Map**)緩存中 * * 能夠回到前面的 {@link AbstractBeanFactory#doGetBean#getSingleton(String)} 方法 * 加載 Bean 的過程會先從緩存中獲取單例 Bean,能夠避免單例模式 Bean 循環依賴注入的問題 */ addSingletonFactory(beanName, // ObjectFactory 實現類 () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. // 開始初始化 `bean` Object exposedObject = bean; try { // <4> 對 `bean` 進行屬性填充,注入對應的屬性值 populateBean(beanName, mbd, instanceWrapper); // <5> 初始化這個 `exposedObject`,調用其初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } // <6> 循環依賴注入的檢查 if (earlySingletonExposure) { // <6.1> 獲取當前正在建立的 `beanName` 被依賴注入的早期引用 // 注意,這裏有一個入參是 `false`,不會調用上面第 `3` 步的 ObjectFactory 實現類 // 也就是說當前 `bean` 若是出現循環依賴注入,這裏才能獲取到提早暴露的引用 Object earlySingletonReference = getSingleton(beanName, false); // <6.2> 若是出現了循環依賴注入,則進行接下來的檢查工做 if (earlySingletonReference != null) { // <6.2.1> 若是 `exposedObject` 沒有在初始化階段中被改變,也就是沒有被加強 // 則使用提早暴露的那個引用 if (exposedObject == bean) { exposedObject = earlySingletonReference; } // <6.2.2> 不然,`exposedObject` 已經不是被別的 Bean 依賴注入的那個 Bean else if (!this.allowRawInjectionDespiteWrapping // 是否容許注入未加工的 Bean,默認爲 false,這裏取非就爲 true && hasDependentBean(beanName)) { // 存在依賴 `beanName` 的 Bean(經過 `depends-on` 配置) // 獲取依賴當前 `beanName` 的 Bean 們的名稱(經過 `depends-on` 配置) String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); // 接下來進行判斷,若是依賴 `beanName` 的 Bean 已經建立 // 說明當前 `beanName` 被注入了,而這裏最終的 `bean` 被包裝過,不是以前被注入的 // 則拋出異常 for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { /** * <7> 爲當前 `bean` 註冊 DisposableBeanAdapter(若是須要的話),用於 Bean 生命週期中的銷燬階段 * 能夠看到 {@link DefaultSingletonBeanRegistry#destroySingletons()} 方法 */ registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } // <8> 返回建立好的 `exposedObject` 對象 return exposedObject; }
這個方法的處理過程有點長,以下:
Bean 的實例化階段,會將 Bean 的實例對象封裝成 BeanWrapperImpl 包裝對象
若是是單例模式,則先嚐試從 factoryBeanInstanceCache
緩存中獲取實例對象,並從緩存中移除
使用合適的實例化策略來建立 Bean 的實例:工廠方法、構造函數自動注入、簡單初始化,主要是將 BeanDefinition 轉換爲 BeanWrapper 對象
調用 createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法
獲取包裝的實例對象 bean
獲取包裝的實例對象的類型 beanType
對 RootBeanDefinition(合併後)進行加工處理
@Autowired
和 @Value
註解標註的屬性的注入元信息,後續進行依賴注入@Resource
註解標註的屬性的注入元信息,後續進行依賴注入,它也會找到 @PostConstruct
和 @PreDestroy
註解標註的方法,並構建一個 LifecycleMetadata 對象,用於後續生命週期中的初始化和銷燬提早暴露這個 bean
,若是能夠的話,目的是解決單例模式 Bean 的循環依賴注入
bean
,提早暴露,保存在 singletonFactories
(三級 Map)緩存中接下來開始初始化上面的 bean
實例對象,會先建立一個 Object exposedObject
等於 bean
(引用)
bean
進行屬性填充,注入對應的屬性值,調用 populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
方法exposedObject
,調用其初始化方法,調用 initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
方法循環依賴注入的檢查
beanName
被依賴注入的早期引用,調用 DefaultSingletonBeanRegistry#getSingleton(String beanName, boolean allowEarlyReference)
方法。注意,這裏有一個入參是 false
,不會調用上面第 3
步的 ObjectFactory 實現類,也就是說當前 bean
若是出現循環依賴注入,這裏才能獲取到提早暴露的引用exposedObject
沒有在初始化階段中被改變,也就是沒有被加強,則使用提早暴露的那個引用exposedObject
已經不是被別的 Bean 依賴注入的那個 Bean,若是依賴當前 beanName
的 Bean(經過 depends-on
配置)已經被建立,則拋出異常爲當前 bean
註冊 DisposableBeanAdapter(若是須要的話),用於 Bean 生命週期中的銷燬階段
返回建立好的 exposedObject
對象
歸納:
關於上面建立 Bean 的兩個方法的相關步驟沒有展開討論,下面會依次進行分析
對應代碼段:
// AbstractAutowireCapableBeanFactory#createBean(...) 方法 // <1> 獲取 `mbd` 對應的 Class 對象,確保當前 Bean 可以被建立出來 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); // 若是這裏獲取到了 Class 對象,可是 `mbd` 中沒有 Class 對象的相關信息,表示這個 Class 對象是動態解析出來的 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { // 複製一份 `mbd`,並設置 Class 對象,由於動態解析出來的 Class 對象不被共享 mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); }
建立一個 Java 對象以前,須要確保存在對應的 Class 對象。若是這裏獲取到了 Class 對象,可是 mbd
中沒有 Class 對象的相關信息,表示這個 Class 對象是動態解析出來的,則須要複製一份 mbd
,並設置 Class 對象,由於動態解析出來的 Class 對象不被共享
resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
,獲取 beanName
的 Class 對象,方法以下:
// AbstractBeanFactory.java @Nullable protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch) throws CannotLoadBeanClassException { try { // 有 Class 對象則直接返回 if (mbd.hasBeanClass()) { return mbd.getBeanClass(); } // 不然,調用 `doResolveBeanClass(...)` 方法,加載出一個 Class 對象 if (System.getSecurityManager() != null) { return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); } else { return doResolveBeanClass(mbd, typesToMatch); } } // ... 省略 catch 各類異常 }
若是有 Class 對象則直接返回,沒有的話調用 doResolveBeanClass(...)
方法去獲取 Class 對象
// AbstractBeanFactory.java @Nullable private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException { // 獲取 ClassLoader 加載器 ClassLoader beanClassLoader = getBeanClassLoader(); ClassLoader dynamicLoader = beanClassLoader; boolean freshResolve = false; if (!ObjectUtils.isEmpty(typesToMatch)) { // When just doing type checks (i.e. not creating an actual instance yet), // use the specified temporary class loader (e.g. in a weaving scenario). ClassLoader tempClassLoader = getTempClassLoader(); if (tempClassLoader != null) { dynamicLoader = tempClassLoader; freshResolve = true; if (tempClassLoader instanceof DecoratingClassLoader) { DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; for (Class<?> typeToMatch : typesToMatch) { dcl.excludeClass(typeToMatch.getName()); } } } } // 獲取 `className` String className = mbd.getBeanClassName(); if (className != null) { // 根據 BeanExpressionResolver 表達式處理器計算出 `className` 對應的結果 // 可能仍是一個類名稱,也多是一個 Class 對象 Object evaluated = evaluateBeanDefinitionString(className, mbd); if (!className.equals(evaluated)) { // A dynamically resolved expression, supported as of 4.2... if (evaluated instanceof Class) { return (Class<?>) evaluated; } else if (evaluated instanceof String) { className = (String) evaluated; freshResolve = true; } else { throw new IllegalStateException("Invalid class name expression result: " + evaluated); } } // 若是被處理過,則根據這個 `className` 建立一個 Class 對象 // 建立的 Class 對象不會設置到 `mbd` 中 if (freshResolve) { // When resolving against a temporary class loader, exit early in order // to avoid storing the resolved Class in the bean definition. if (dynamicLoader != null) { try { return dynamicLoader.loadClass(className); } catch (ClassNotFoundException ex) { if (logger.isTraceEnabled()) { logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex); } } } return ClassUtils.forName(className, dynamicLoader); } } // Resolve regularly, caching the result in the BeanDefinition... // 讓 RootBeanDefinition 本身解析出 Class 對象 return mbd.resolveBeanClass(beanClassLoader); }
暫時忽略上面具體的每一個細節,底層會根據 className
經過來加載器獲取對應的 Class 對象,並設置到 RootBeanDefinition
注意,這個過程多是動態解析出來的,例如 className
是一個表達式,經過 BeanDefinition 表達式解析器解析出來的,而後根據其獲取 Class 對象,這裏是不會設置到 RootBeanDefinition 中
對應代碼段:
// AbstractAutowireCapableBeanFactory#createBean(...) 方法 try { // <2> 對全部的 MethodOverride 進行驗證和準備工做(確保存在對應的方法,並設置爲不能重複加載) mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); }
<lookup-method />
和 <replace-method />
標籤會被解析成 LookupOverride 和 ReplaceOverride 對象,用於實現或覆蓋某個方法,這裏會進行驗證和準備工做,過程以下:
// AbstractBeanDefinition.java public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exist and determine their overloaded status. if (hasMethodOverrides()) { // 若是存在 `methodOverrides` // 獲取全部的 override method,遍歷進行處理 getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride); } } protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); if (count == 0) { throw new BeanDefinitionValidationException( "Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + getBeanClassName() + "]"); } else if (count == 1) { // Mark override as not overloaded, to avoid the overhead of arg type checking. mo.setOverloaded(false); } }
確保這個類中存在對應的方法,並設置爲不能重複加載
對應代碼段:
// AbstractAutowireCapableBeanFactory#createBean(...) 方法 try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. /** * <3> 在實例化前進行相關處理,會先調用全部 {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} * 注意,若是這裏返回對象不是 `null` 的話,不會繼續往下執行本來初始化操做,直接返回,也就是說這個方法返回的是最終實例對象 * 能夠經過這種方式提早返回一個代理對象,例如 AOP 的實現,或者 RPC 遠程調用的實現(由於本地類沒有遠程能力,能夠經過這種方式進行攔截) */ Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); }
在開始建立 Bean 執行,調用 resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)
方法進行處理,嘗試獲取一個代理對象
注意,若是這裏返回對象不是 null
的話,不會繼續往下執行本來初始化操做,直接返回,也就是說這個方法返回的是最終實例對象。能夠經過這種方式提早返回一個代理對象,例如 AOP 的實現,或者 RPC 遠程調用的實現(由於本地類沒有遠程能力,能夠經過這種方式進行攔截)
// AbstractAutowireCapableBeanFactory.java @Nullable protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. // 若是 RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的),而且存在 InstantiationAwareBeanPostProcessor 處理器 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { // 實例化前置處理 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { // 後置處理 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
若是 RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的),而且存在 InstantiationAwareBeanPostProcessor 處理器,則進行下面的處理:
實例化前置處理,調用 applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
方法,以下:
@Nullable protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
遍歷全部的 InstantiationAwareBeanPostProcessor 處理器,執行 postProcessBeforeInstantiation 方法,實例化前置處理,若是有一個處理後返回的結果不爲空則直接返回
若是第 1
步返回的對象不爲空,則調用 applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
方法,以下:
// AbstractAutowireCapableBeanFactory.java @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 遍歷 BeanPostProcessor for (BeanPostProcessor processor : getBeanPostProcessors()) { // 處理 Object current = processor.postProcessAfterInitialization(result, beanName); // 返回空,則返回 result if (current == null) { return result; } // 修改 result result = current; } return result; }
遍歷全部的 BeanPostProcessor 處理器,執行 postProcessAfterInitialization 方法,初始化後置處理
對應代碼段:
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法 // Instantiate the bean. /** * <1> Bean 的實例化階段,會將 Bean 的實例對象封裝成 {@link BeanWrapperImpl} 包裝對象 * BeanWrapperImpl 承擔的角色: * 1. Bean 實例的包裝 * 2. {@link org.springframework.beans.PropertyAccessor} 屬性編輯器 * 3. {@link org.springframework.beans.PropertyEditorRegistry} 屬性編輯器註冊表 * 4. {@link org.springframework.core.convert.ConversionService} 類型轉換器(Spring 3+,替換了以前的 TypeConverter) */ BeanWrapper instanceWrapper = null; // <1.1> 若是是單例模式,則先嚐試從 `factoryBeanInstanceCache` 緩存中獲取實例對象,並從緩存中移除 if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } // <1.2> 使用合適的實例化策略來建立 Bean 的實例:工廠方法、構造函數自動注入、簡單初始化 // 主要是將 BeanDefinition 轉換爲 BeanWrapper 對象 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } // <1.3> 獲取包裝的實例對象 `bean` final Object bean = instanceWrapper.getWrappedInstance(); // <1.4> 獲取包裝的實例對象的類型 `beanType` Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; }
Bean 的實例化階段,會將 Bean 的實例對象封裝成 BeanWrapperImpl 包裝對象,BeanWrapperImpl 承擔的角色:
該過程大體以下
factoryBeanInstanceCache
緩存中獲取實例對象,並從緩存中移除createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法bean
beanType
createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
方法,建立一個 Bean 的實例對象,以下:
// AbstractAutowireCapableBeanFactory.java protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. // <1> 獲取 `beanName` 對應的 Class 對象 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()); } // <2> 若是存在 Supplier 實例化回調接口,則使用給定的回調方法建立一個實例對象 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } // <3> 若是配置了 `factory-method` 工廠方法,則調用該方法來建立一個實例對象 // 經過 @Bean 標註的方法會經過這裏進行建立 if (mbd.getFactoryMethodName() != null) { // 這個過程很是複雜,你能夠理解爲: // 找到最匹配的 Method 工廠方法,獲取相關參數(依賴注入),而後經過調用該方法返回一個實例對象(反射機制) return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... // <4> 判斷這個 RootBeanDefinition 的構造方法是否已經被解析出來了 // 由於找到最匹配的構造方法比較繁瑣,找到後會設置到 RootBeanDefinition 中,避免重複這個過程 boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { // 加鎖 // <4.1> 構造方法已經解析出來了 if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; // <4.2> 這個構造方法有入參,表示須要先獲取到對應的入參(構造器注入) autowireNecessary = mbd.constructorArgumentsResolved; } } } // <5> 若是最匹配的構造方法已解析出來 if (resolved) { // <5.1> 若是這個構造方法有入參 if (autowireNecessary) { // 這個過程很複雜,你能夠理解爲: // 找到最匹配的構造方法,這裏會拿到已經被解析出來的這個方法,並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制) return autowireConstructor(beanName, mbd, null, null); } // <5.2> 不然,沒有入參 else { // 直接調用解析出來構造方法,返回一個實例對象(反射機制) return instantiateBean(beanName, mbd); } } // Candidate constructors for autowiring? // <6> 若是最匹配的構造方法還沒開始解析,那麼須要找到一個最匹配的構造方法,而後建立一個實例對象 /** * <6.1> 嘗試經過 SmartInstantiationAwareBeanPostProcessor 處理器的 determineCandidateConstructors 方法來找到一些合適的構造方法 * 參考 {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors} */ Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // <6.2> 是否知足下面其中一個條件 if (ctors != null // 上一步找到了合適的構造方法 || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR // 構造器注入 || mbd.hasConstructorArgumentValues() // 定義了構造方法的入參 || !ObjectUtils.isEmpty(args)) // 當前方法指定了入參 { // 找到最匹配的構造方法,若是 `ctors` 不爲空,會從這裏面找一個最匹配的, // 並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制) return autowireConstructor(beanName, mbd, ctors, args); } // Preferred constructors for default construction? /** * <7> 若是第 `6` 步還不知足,那麼嘗試獲取優先的構造方法 * 參考 {@link org.springframework.context.support.GenericApplicationContext.ClassDerivedBeanDefinition} */ ctors = mbd.getPreferredConstructors(); if (ctors != null) { // 若是存在優先的構造方法,則從裏面找到最匹配的一個,並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制) return autowireConstructor(beanName, mbd, ctors, null); } // No special handling: simply use no-arg constructor. // <8> 若是上面多種狀況都不知足,那隻能使用兜底方法了,直接調用默認構造方法返回一個實例對象(反射機制) return instantiateBean(beanName, mbd); }
過程大體以下:
獲取 beanName
對應的 Class 對象
若是存在 Supplier 實例化回調接口,則使用給定的回調方法建立一個實例對象
若是配置了 factory-method
工廠方法,則調用該方法來建立一個實例對象,經過 @Bean 標註的方法會經過這裏進行建立
若是上面兩種狀況都不是,那麼就進行接下來正常建立 Bean 實例的一個過程
判斷這個 RootBeanDefinition 的構造方法是否已經被解析出來了,由於找到最匹配的構造方法比較繁瑣,找到後會設置到 RootBeanDefinition 中,避免重複這個過程
resolvedConstructorOrFactoryMethod
是否不爲空,不爲空表示構造方法已經解析出來了constructorArgumentsResolved
是否不爲空,不爲空表示有入參,須要先獲取到對應的入參(構造器注入)若是最匹配的構造方法已解析出來
若是最匹配的構造方法還沒開始解析,那麼須要找到一個最匹配的構造方法,而後建立一個實例對象
先嚐試經過 SmartInstantiationAwareBeanPostProcessor 處理器找到一些合適的構造方法,保存在 ctors
中
是否知足下面其中一個條件:ctors
不爲空、構造器注入模式、定義了構造方法的入參、當前方法指定了入參,
則找到最匹配的構造方法,若是 ctors
不爲空,會從這裏面找一個最匹配的,並找到入參(構造器注入),而後調用該方法返回一個實例對象(反射機制)
若是第 6
步還不知足,那麼嘗試從 RootBeanDefinition 中獲取優先的構造方法
若是上面多種狀況都不知足,那隻能使用兜底方法了,直接調用默認構造方法返回一個實例對象(反射機制)
整個的實例化過程很是的複雜,接下來進行歸納:
先拿到對應 Class 對象
若是設置了 Supplier 實例化回調接口,則經過該回調接口獲取實例對象
若是配置了經過 factory-method
工廠方法獲取實例對象,則經過這個方法建立實例對象,@Bean 標註的方法也是經過這裏建立實例對象,方法入參會依賴注入
找到最匹配的一個構造方法,並找到對應的入參(構造器注入),經過調用該方法返回一個實例對象
兜底方法,調用默認構造方法建立一個實例對象
由於整個過程比較繁瑣,涉及到的方法行數比較多,因此另起一篇《Bean 的實例化階段》文章進行分析
對應代碼段:
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法 // Allow post-processors to modify the merged bean definition. // <2> 對 RootBeanDefinition(合併後)進行加工處理 synchronized (mbd.postProcessingLock) { // 加鎖,線程安全 // <2.1> 若是該 RootBeanDefinition 沒有處理過,則進行下面的處理 if (!mbd.postProcessed) { try { /** * <2.2> 對 RootBeanDefinition(合併後)進行加工處理 * 調用全部 {@link MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition} * 【重要】例若有下面兩個處理器: * 1. AutowiredAnnotationBeanPostProcessor 會先解析出 @Autowired 和 @Value 註解標註的屬性的注入元信息,後續進行依賴注入; * 2. CommonAnnotationBeanPostProcessor 會先解析出 @Resource 註解標註的屬性的注入元信息,後續進行依賴注入, * 它也會找到 @PostConstruct 和 @PreDestroy 註解標註的方法,並構建一個 LifecycleMetadata 對象,用於後續生命週期中的初始化和銷燬 */ applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } // <2.3> 設置該 RootBeanDefinition 被處理過,避免重複處理 mbd.postProcessed = true; } }
在建立好實例對象後,容許你經過 MergedBeanDefinitionPostProcessor 處理器對該 RootBeanDefinition 進行加工處理,也能夠從中獲取相關信息
若是該 RootBeanDefinition 沒有加工處理過,則進行下面的處理,不然忽略該過程
對 RootBeanDefinition(合併後)進行加工處理,調用 applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
方法,以下:
// AbstractAutowireCapableBeanFactory.java protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }
調用全部 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition 方法對 RootBeanDefinition 進行加工處理,例如:AutowiredAnnotationBeanPostProcessor 會先解析出 @Autowired
和 @Value
註解標註的屬性的注入元信息,後續進行依賴注入;CommonAnnotationBeanPostProcessor 會先解析出 @Resource
註解標註的屬性的注入元信息,後續進行依賴注入,它也會找到 @PostConstruct
和 @PreDestroy
註解標註的方法,並構建一個 LifecycleMetadata 對象,用於後續生命週期中的初始化和銷燬
設置該 RootBeanDefinition 被處理過,避免重複處理
這個過程在後續講經過 @Autowired 依賴注入的實現原理會被提到
對應代碼段:
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法 // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. // <3> 提早暴露這個 `bean`,若是能夠的話,目的是解決單例模式 Bean 的循環依賴注入 // <3.1> 判斷是否能夠提早暴露 boolean earlySingletonExposure = (mbd.isSingleton() // 單例模式 && this.allowCircularReferences // 容許循環依賴,默認爲 true && isSingletonCurrentlyInCreation(beanName)); // 當前單例 bean 正在被建立,在前面已經標記過 if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } /** * <3.2> * 建立一個 ObjectFactory 實現類,用於返回當前正在被建立的 `bean`,提早暴露,保存在 `singletonFactories` (**三級 Map**)緩存中 * * 能夠回到前面的 {@link AbstractBeanFactory#doGetBean#getSingleton(String)} 方法 * 加載 Bean 的過程會先從緩存中獲取單例 Bean,能夠避免單例模式 Bean 循環依賴注入的問題 */ addSingletonFactory(beanName, // ObjectFactory 實現類 () -> getEarlyBeanReference(beanName, mbd, bean)); }
在建立好實例對象後,此時尚未進行屬性的填充和初始化等工做,先判斷是否能夠提早暴露這個實例對象,目的是解決單例模式 Bean 的循環依賴注入
判斷是否能夠提早暴露,知足這些條件:單例模式、容許循環依賴(默認爲 true)、當前單例 Bean 正在被建立(前面已經標記過)
若是能夠的話,先經過 Lambda 表達式建立一個 ObjectFactory 實現類,以下:
// AbstractAutowireCapableBeanFactory.java protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() // RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的) && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }
入參 bean
爲當前 Bean 的實例對象(未初始化),這個實現類容許經過 SmartInstantiationAwareBeanPostProcessor 對這個提早暴露的對象進行處理,最終會返回這個提早暴露的對象
而後調用 addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)
方法,以下:
// DefaultSingletonBeanRegistry.java protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } }
能夠看到會往 singletonFactories
集合(三級 Map)中添加當前 beanName
和 singletonFactory
(ObjectFactory 實現類)的映射關係;
從 earlySingletonObjects
集合(二級 Map)中移除當前 beanName
;
往 registeredSingletons
集合(已註冊的 Bean 的名稱集合)中添加當前 beanName
能夠回到《開啓 Bean 的加載》文章中2. 從緩存中獲取單例 Bean小節,當這個 Bean 出現循環依賴注入了,是否是能夠避免相關問題,由於能夠經過這個 ObjectFactory 實現類獲取到提早暴露的對象
由於循環依賴注入的處理貫穿整個 Bean 的加載過程,因此另起一篇《單例 Bean 的循環依賴處理》文章進行分析
對應代碼段:
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法 // Initialize the bean instance. // 開始初始化 `bean` Object exposedObject = bean; try { // <4> 對 `bean` 進行屬性填充,注入對應的屬性值 populateBean(beanName, mbd, instanceWrapper); // <5> 初始化這個 `exposedObject`,調用其初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } }
在建立好實例對象後,這個對象的屬性尚未賦值,因此將這個實例對象的相關屬性進行賦值,也就是上面的第 <4>
步
populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)
方法,屬性填充,以下:
// AbstractAutowireCapableBeanFactory.java protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // <1> 若是實例對象爲空,則進行下面的判斷 if (bw == null) { // <1.1> 這個 Bean 有屬性,則拋出異常 if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } // <1.2> 不然,不用屬性填充,直接 `return` else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. // <2> 實例化階段的後置處理,若是知足這兩個條件 if (!mbd.isSynthetic() // RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的) && hasInstantiationAwareBeanPostProcessors()) { // 是否有 InstantiationAwareBeanPostProcessor 處理器 // <2.1> 遍歷全部的 BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { // 若是爲 InstantiationAwareBeanPostProcessor 類型 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // <2.2> 對實例化對象進行後置處理 // 注意若是返回 false,直接 `return`,不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // <3> 獲取 `pvs`,承載當前對象的屬性值 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // <4> 獲取這個 Bean 的注入模式,默認爲 **AUTOWIRE_NO**,例如能夠經過 `@Bean` 註解的 `autowire` 屬性配置注入模式 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // <4.1> 若是注入模式爲 **AUTOWIRE_BY_NAME** 或者 **AUTOWIRE_BY_TYPE**,則經過下面的方式獲取屬性值 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { // <4.2> 將 `pvs` 封裝成 MutablePropertyValues 對象 `newPvs`(容許對屬性進行相關操做) MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. // <4.3> **AUTOWIRE_BY_NAME** 模式,經過名稱獲取相關屬性值,保存在 `newPvs` 中 if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. // <4.4> **AUTOWIRE_BY_TYPE** 模式,經過類型獲取相關屬性值,保存在 `newPvs` 中 if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } // <4.5> 將 `newPvs` 複製給 `pvs` pvs = newPvs; } // 是否有 InstantiationAwareBeanPostProcessor 處理器 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 是否須要進行依賴檢查,默認爲 true boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; // <5> 經過 InstantiationAwareBeanPostProcessor 處理器(若是有)對 `pvs` 進行處理 if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } // <5.1> 遍歷全部的 BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { // 若是爲 InstantiationAwareBeanPostProcessor 類型 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; /** * Spring 內部的 InstantiationAwareBeanPostProcessor 處理器: * {@link AutowiredAnnotationBeanPostProcessor#postProcessProperties} 會解析 @Autowired 和 @Value 註解標註的屬性,獲取對應屬性值; * {@link org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties} 會 解析 Resource 註解標註的屬性,獲取對應的屬性值 */ // <5.2> 調用處理器的 `postProcessProperties(...)` 方法,對 `pvs` 進行後置處理 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); // <5.3> 若是上一步的處理結果爲空,多是新版本致使的(Spring 5.1 以前沒有上面這個方法),則須要兼容老版本 if (pvsToUse == null) { // <5.3.1> 找到這個 Bean 的全部 `java.beans.PropertyDescriptor` 屬性描述器(包含這個屬性的全部信息) if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // <5.3.2> 調用處理器的 `postProcessPropertyValues(...)` 方法,對 `pvs` 進行後置處理 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); // <5.3.3> 若是處理後的 PropertyValues 對象爲空,直接 `return`,則不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充 if (pvsToUse == null) { return; } } // <5.4> 將處理後的 `pvsToUse` 複製給 `pvs` pvs = pvsToUse; } } } // <6> 依賴檢查 if (needsDepCheck) { // <6.1> 找到這個 Bean 的全部 `java.beans.PropertyDescriptor` 屬性描述器(包含這個屬性的全部信息) if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // <6.2> 依賴檢查,若是沒有找到對應的屬性值,則根據檢查策略進行拋出異常(默認不會) checkDependencies(beanName, mbd, filteredPds, pvs); } // <7> 若是 `pvs` 不爲空,則將裏面的屬性值設置到當前 Bean 對應的屬性中(依賴注入) // 前面找到的屬性值並無設置到 Bean 中,且屬性值多是一個表達式,類型也可能也不對,須要先進行處理和類型轉換,而後再設置到該實例對象中 if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
過程大體以下:
若是實例對象爲null
,則進行下面的判斷
return
實例化階段的後置處理,若是知足這兩個條件:RootBeanDefinition 不是用戶定義的(由 Spring 解析出來的)、是否有 InstantiationAwareBeanPostProcessor 處理器
遍歷全部的 BeanPostProcessor
若是爲 InstantiationAwareBeanPostProcessor 類型,則對實例化對象進行後置處理
注意,若是返回 false,直接 return
,不會調用後面的 InstantiationAwareBeanPostProcessor 處理器,也不會進行接下來的屬性填充
獲取 pvs
,承載當前對象的屬性值
獲取這個 Bean 的注入模式,默認爲 AUTOWIRE_NO,例如能夠經過 @Bean
註解的 autowire
屬性配置注入模式
pvs
封裝成 MutablePropertyValues 對象 newPvs
(容許對屬性進行相關操做)newPvs
中,調用 autowireByName(...)
方法newPvs
中,調用 autowireByType(...)
方法newPvs
複製給 pvs
經過 InstantiationAwareBeanPostProcessor 處理器(若是有)對 pvs
進行處理
postProcessProperties(...)
方法,對 pvs
進行後置處理java.beans.PropertyDescriptor
屬性描述器(包含這個屬性的全部信息)postProcessPropertyValues(...)
方法,對 pvs
進行後置處理return
,則不會調用後面的處理器,也不會進行接下來的屬性填充pvsToUse
複製給 pvs
依賴檢查
java.beans.PropertyDescriptor
屬性描述器(包含這個屬性的全部信息)若是 pvs
不爲空,則將裏面的屬性值設置到當前 Bean 對應的屬性中(依賴注入),調用 applyPropertyValues(...)
方法
前面找到的屬性值並無設置到 Bean 中,且屬性值多是一個表達式,類型也可能也不對,須要先進行處理和類型轉換,而後再設置到該實例對象中
整個的屬性填充過程很是的複雜,接下來進行歸納:
false
表示不須要進行接下來的屬性填充過程@Autowired
、@Value
等註解標註的屬性會經過這裏找到對應的屬性值(或對象)由於整個過程比較繁瑣,涉及到的方法行數比較多,因此另起一篇《Bean 的屬性填充階段》文章進行分析
對應代碼段:
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法 // Initialize the bean instance. // 開始初始化 `bean` Object exposedObject = bean; try { // <4> 對 `bean` 進行屬性填充,注入對應的屬性值 populateBean(beanName, mbd, instanceWrapper); // <5> 初始化這個 `exposedObject`,調用其初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } }
實例對象已經有了,且相關屬性已經填充了,那麼接下來須要進行相關初始化工做,也就是上面的第 <5>
步
// AbstractAutowireCapableBeanFactory.java protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { // 安全模式 // <1> Aware 接口的回調 AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // <1> Aware 接口的回調 invokeAwareMethods(beanName, bean); } /** * <2> **初始化**階段的**前置處理**,執行全部 BeanPostProcessor 的 postProcessBeforeInitialization 方法 * * 在 {@link AbstractApplicationContext#prepareBeanFactory} 方法中會添加 {@link ApplicationContextAwareProcessor} 處理器 * 用於處理其餘 Aware 接口的回調,例如ApplicationContextAware、EnvironmentAware、ApplicationEventPublisherAware * * 在 {@link AnnotationConfigUtils#registerAnnotationConfigProcessors} 方法中會註冊 {@link CommonAnnotationBeanPostProcessor} 處理器 * 在這裏會執行 @PostConstruct 註解標註的方法 */ Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // <3> 激活自定義的初始化方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } /** * <4> **初始化**階段的**後置處理**,執行全部 BeanPostProcessor 的 postProcessAfterInitialization 方法 * * 在 {@link AbstractApplicationContext#prepareBeanFactory} 方法中會添加 {@link ApplicationListenerDetector} 處理器 * 若是是單例 Bean 且爲 ApplicationListener 類型,則添加到 Spring 應用上下文,和 Spring 事件相關 */ if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
初始化過程以下:
Aware 接口的回調,調用 invokeAwareMethods(final String beanName, final Object bean)
方法,以下:
// AbstractAutowireCapableBeanFactory.java private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
若是是 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware,則調用其 setXxx
方法
初始化階段的前置處理,執行全部 BeanPostProcessor 的 postProcessBeforeInitialization 方法,以下:
// AbstractAutowireCapableBeanFactory.java @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 遍歷全部 BeanPostProcessor for (BeanPostProcessor processor : getBeanPostProcessors()) { // 初始化的前置處理,返回 `current` 處理結果 Object current = processor.postProcessBeforeInitialization(result, beanName); // 處理結果爲空,則直接返回 `result` if (current == null) { return result; } // 不然,`result` 複製 `current` result = current; } return result; }
例如 Spring 內部有下面兩個處理器
ApplicationContextAwareProcessor:ApplicationContextAware、ApplicationEventPublisherAware、EnvironmentAware 等其餘 Aware 接口的回調
CommonAnnotationBeanPostProcessor: @PostConstruct
註解標註的方法的調用
激活自定義的初始化方法,以下:
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { // <1> InitializingBean 接口的回調(若是是) boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { // 安全模式 try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { // 調用其 afterPropertiesSet() 方法 ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 調用其 afterPropertiesSet() 方法 ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { // <2> 調用經過 `init-method` 指定的初始化方法(反射機制) invokeCustomInitMethod(beanName, bean, mbd); } } }
afterPropertiesSet()
方法init-method
指定的初始化方法(反射機制)初始化階段的後置處理,執行全部 BeanPostProcessor 的 postProcessAfterInitialization 方法,以下:
// AbstractAutowireCapableBeanFactory.java @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 遍歷全部 BeanPostProcessor for (BeanPostProcessor processor : getBeanPostProcessors()) { // 初始化的後置處理,返回 `current` 處理結果 Object current = processor.postProcessAfterInitialization(result, beanName); // 處理結果爲空,則直接返回 `result` if (current == null) { return result; } // 不然,`result` 複製 `current` result = current; } return result; }
例如 Spring 內部有一個 ApplicationListenerDetector 處理器,若是是單例 Bean 且爲 ApplicationListener 類型,則添加到 Spring 應用上下文,和 Spring 事件相關
整個的初始化過程並不複雜,其中也有對應的擴展點,初始化前置處理和後置處理,總的歸納以下:
Aware
接口的回調
JSR-250 @PostConstruct
標註的方法的調用
InitializingBean#afterPropertiesSet
方法的回調
init-method
初始化方法的調用
對應代碼段:
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法 // <6> 循環依賴注入的檢查 if (earlySingletonExposure) { // <6.1> 獲取當前正在建立的 `beanName` 被依賴注入的早期引用 // 注意,這裏有一個入參是 `false`,不會調用上面第 `3` 步的 ObjectFactory 實現類 // 也就是說當前 `bean` 若是出現循環依賴注入,這裏才能獲取到提早暴露的引用 Object earlySingletonReference = getSingleton(beanName, false); // <6.2> 若是出現了循環依賴注入,則進行接下來的檢查工做 if (earlySingletonReference != null) { // <6.2.1> 若是 `exposedObject` 沒有在初始化階段中被改變,也就是沒有被加強 // 則使用提早暴露的那個引用 if (exposedObject == bean) { exposedObject = earlySingletonReference; } // <6.2.2> 不然,`exposedObject` 已經不是被別的 Bean 依賴注入的那個 Bean else if (!this.allowRawInjectionDespiteWrapping // 是否容許注入未加工的 Bean,默認爲 false,這裏取非就爲 true && hasDependentBean(beanName)) { // 存在依賴 `beanName` 的 Bean(經過 `depends-on` 配置) // 獲取依賴當前 `beanName` 的 Bean 們的名稱(經過 `depends-on` 配置) String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); // 接下來進行判斷,若是依賴 `beanName` 的 Bean 已經建立 // 說明當前 `beanName` 被注入了,而這裏最終的 `bean` 被包裝過,不是以前被注入的 // 則拋出異常 for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } }
在前面 6. 提早暴露當前 Bean 小節中,若是提早暴露了 Bean,則可能存在循環依賴注入,這裏須要進行一些檢查,過程大體以下:
獲取當前正在建立的 beanName
被依賴注入的早期引用,這裏調用方法也就是從緩存中獲取單例 Bean 的方法。
注意,這裏有一個入參是 false
,不會調用前面 6. 提早暴露當前 Bean 小節中緩存的 ObjectFactory 實現類,也就是說當前 bean
若是出現循環依賴注入,這裏才能獲取到提早暴露的引用
若是上一步獲取到了提早暴露的引用,也就是出現了循環依賴注入,則進行接下來的檢查工做
exposedObject
沒有在初始化階段中被改變,也就是沒有被加強,則使用提早暴露的那個引用exposedObject
已經不是被別的 Bean 依賴注入的那個 Bean,則進行相關判斷當出現循環依賴注入,這裏會檢查填充屬性和初始化的過程當中是否改變了這個 beanName
,改變了的話須要判斷依賴當前 beanName
的 Bean 們是否已經建立了,若是已經建立了,那麼可能它拿到的 beanName
不是這裏初始化後的對象(被修改了),因此須要拋出異常
對應代碼段:
// AbstractAutowireCapableBeanFactory#doCreateBean(...) 方法 // Register bean as disposable. try { /** * <7> 爲當前 `bean` 註冊 DisposableBeanAdapter(若是須要的話),用於 Bean 生命週期中的銷燬階段 * 能夠看到 {@link DefaultSingletonBeanRegistry#destroySingletons()} 方法 */ registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); }
這裏會調用 registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd)
方法,以下:
// AbstractBeanFactory.java protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() // 不是原型模式 && requiresDestruction(bean, mbd)) // 有銷燬的必要,也就是定義了銷燬方法 { if (mbd.isSingleton()) { // 單例模式 // Register a DisposableBean implementation that performs all destruction work for the given bean: // DestructionAwareBeanPostProcessors, DisposableBean interface, custom destroy method. // 建立一個 DisposableBeanAdapter 對象封裝這個 Bean,而後保存在 `disposableBeans` Map 集合中 registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // 其餘模式 // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } // 建立一個 DisposableBeanAdapter 對象封裝這個 Bean,往其餘模式的 Scope 對象裏面註冊 scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
若是不是原型模式,而且有銷燬的必要,也就是定義了銷燬方法,則須要建立一個 DisposableBeanAdapter 對象封裝這個 Bean,在生命週期的銷燬階段須要先經過這個對象先執行銷燬方法,這個對象如何存儲的:
disposableBeans
Map 集合中通過上面一系列的過程,實例化、屬性填充、初始化等階段,已經建立好了這個 Bean,最後直接返回
當咱們顯示或者隱式地調用AbstractBeanFactory
的 getBean(...)
方法時,會觸發 Bean 的加載,加載過程在上一篇《開啓 Bean 的加載》文章中已經分析過。對於不一樣做用域的 Bean,底層都會調用 AbstractAutowireCapableBeanFactory
的 createBean(...)
方法進行建立,建立 Bean 的過程以下:
建立 Bean 的過程很是複雜,在不一樣的階段都會講到 BeanPostProcessor(及其子類)的身影,Spring 內部不少功能都是基於該處理器接口實現的,固然開發者也能夠經過其進行拓展,使得框架變得很是靈活。其中 Bean 的實例化和屬性填充兩個階段比較複雜,這裏沒有深刻分析,可參考後續文章。提早暴露單例 Bean 循環依賴處理的關鍵,後續文章也會再次分析。
你是否還有疑問,例如咱們經常使用的 @Autowired、@Value、@Resource、@Bean、@Import、@ComponentScan 等註解會在哪被解析呢?
彆着急,後面的文章都會講到,咱們先把 Bean 的加載過程搞明白,而後再講 Spring 應用上下文的生命週期