Spring IOC 初始化重新整理流程十一:finishBeanFactoryInitialization(beanFactory)
Spring IOC 初始化重新整理流程:https://www.cnblogs.com/jhxxb/p/13609289.html
未執行finishBeanFactoryInitialization() 時的容器
容器內所有的單例 Bean: 有的是前面經歷過 getBean() 被提前例項化了,有的是直接 addSingleton() 方法新增的
容器內所有 Bean 的定義資訊:自己 @Bean 進去的目前都僅僅存在於 Bean 定義資訊內,還並沒有真正的例項化
方法原始碼
建立所有非懶載入的單例類(並執行 BeanPostProcessors),我們自定義的 Bean 絕大多數都是在這一步被初始化的,包括依賴注入等
這一步,能讓我們更深入的看到 Spring 是如何管理 Bean 的宣告週期,以及依賴關係。
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context.// 初始化上下文的轉換服務,ConversionService 是一個型別轉換介面 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. // 設定一個內建的值處理器(若沒有的話),該處理器作用有點像一個 PropertyPlaceholderConfigurer Bean if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. // 注意此處已經呼叫了 getBean 方法,初始化 LoadTimeWeaverAware Bean // getBean() 方法的詳細,下面會詳細分解 // LoadTimeWeaverAware 是類載入時織入的意思 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. // 停止使用臨時的類載入器 beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. // 快取(凍結)所有的 bean definition 資料,不期望以後會改變 beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. // 這個就是最重要的方法:會把留下來的 Bean,不是 lazy 懶載入的 bean 都例項化掉 // bean 真正例項化的時刻到了 beanFactory.preInstantiateSingletons(); } public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { @Override public void freezeConfiguration() { this.configurationFrozen = true; this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames); }
preInstantiateSingletons()
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { /** * 此處絕大部分的單例 Bean 定義資訊都會被例項化,但是如果是通過 FactoryBean 定義的,它是懶載入的(如果沒人使用,就先不會例項化。只會到使用的時候才例項化) * 即例項化的時候只會例項化 FactoryBean,要用的時候才會通過 FactoryBean 建立真正要使用 Bean */ @Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. While this may not be part of the regular factory bootstrap, it does otherwise work fine. // 此處目的,把所有的 bean 定義資訊名稱,賦值到一個新的集合中 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 不是抽象類 && 是單例 && 不是懶載入 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 對工廠 Bean 支援:比如第三方框架的繼承經常採用這種方式 if (isFactoryBean(beanName)) { // 拿到工廠 Bean,注意有字首:FACTORY_BEAN_PREFIX Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext() ); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } // true:希望馬上被初始化 if (isEagerInit) { getBean(beanName); } } } else { // 普通單例 Bean 初始化,核心邏輯在方法:doGetBean getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... // SmartInitializingSingleton#afterSingletonsInstantiated:所有非 lazy 的單例 Bean 例項化完成後的回撥方法,Spring4.1 後提供// InitializingBean#afterPropertiesSet:只要自己被建立好了就執行 // 例如 EventListenerMethodProcessor,它在 afterSingletonsInstantiated 方法裡就去處理所有的 Bean 的方法,看哪些被標註了 @EventListener 註解,就提取處理為一個 Listener,通過 addApplicationListener 方法放到容器中 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { // 比如:ScheduledAnnotationBeanPostProcessor、CacheAspectSupport、MBeanExporter 等 smartSingleton.afterSingletonsInstantiated(); } } } }
getMergedLocalBeanDefinition()
Bean 定義公共的抽象類是 AbstractBeanDefinition,普通的 Bean 在 Spring 載入 Bean 定義的時候,例項化出來的是 GenericBeanDefinition,而 Spring 上下文包括例項化所有 Bean 用的 AbstractBeanDefinition 是 RootBeanDefinition,這時候就使用getMergedLocalBeanDefinition 方法做了一次轉化,將非 RootBeanDefinition 轉換為 RootBeanDefinition 以供後續操作。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { /** * 該方法功能說明:在 map 快取中把 Bean 的定義拿出來。交給 getMergedLocalBeanDefinition 處理。最終轉換成 RootBeanDefinition 型別 * 在轉換的過程中,如果 BeanDefinition 的父類不為空,則把父類的屬性也合併到 RootBeanDefinition 中, * 所以 getMergedLocalBeanDefinition 方法的作用就是獲取快取的 BeanDefinition 物件併合並其父類和本身的屬性 * 注意:如果當前 BeanDefinition 存在父 BeanDefinition,會基於父 BeanDefinition 生成一個 RootBeanDefinition,然後再將呼叫 OverrideFrom 子 BeanDefinition 的相關屬性覆寫進去 */ protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); } public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { @Override public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { // 把前面已經儲存在 IOC 容器裡的 BeanDefinition 定義資訊返回 BeanDefinition bd = this.beanDefinitionMap.get(beanName); if (bd == null) { if (logger.isTraceEnabled()) { logger.trace("No bean named '" + beanName + "' found in " + this); } throw new NoSuchBeanDefinitionException(beanName); } return bd; }
至此,finishBeanFactoryInitialization 這一步完成,所有的單例 Bean 已經建立完成並放置容器裡。下面是建立 Bean 的詳細流程。
主要方法 getBean()
頂層介面為 BeanFactory
/** * getBean() 不僅僅是 get,如果 get 不到還可能去例項化一個 Bean 的(預設根據空建構函式進行例項化),因此 args 其實就是為了匹配建構函式而提供的擴充套件功能 * 使用前提: * 1、傳入的引數必須有相對應的建構函式入參與之匹配 * 2、bean 的 scope 必須設定成 prototype,因為動態傳參話 bean 不可以是單例 */ public interface BeanFactory { Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; /** * @since 2.5 */ Object getBean(String name, Object... args) throws BeansException; /** * @since 3.0 */ <T> T getBean(Class<T> requiredType) throws BeansException; /** * @since 4.1 */ <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
抽象實現為 AbstractBeanFactory,複寫了其中 3 個方法,此處的 doGetBean(),就是 Bean 例項化的核心邏輯
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); }
DefaultListableBeanFactory 繼承自 AbstractBeanFactory,複寫了剩餘的 2 個方法
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { @Override public <T> T getBean(Class<T> requiredType) throws BeansException { return getBean(requiredType, (Object[]) null); } // 上面那個方法是呼叫這個方法的邏輯 @Override public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException { Assert.notNull(requiredType, "Required type must not be null"); Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false); if (resolved == null) { throw new NoSuchBeanDefinitionException(requiredType); } return (T) resolved; } @Nullable private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) { // resolveNamedBean 根據 requiredType 去找。若不止一個會拋錯:NoUniqueBeanDefinitionException NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull); if (namedBean != null) { return namedBean.getBeanInstance(); } // 如果子容器裡沒有找到 Bean,還會去父容器(若存在的話)裡找找看 BeanFactory parent = getParentBeanFactory(); if (parent instanceof DefaultListableBeanFactory) { return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull); } else if (parent != null) { ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType); if (args != null) { return parentProvider.getObject(args); } else { return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable()); } } return null; }
getBean() 呼叫的doGetBean()
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { /** * 依賴注入主要有兩個過程,一個是例項化 Bean,另一個是將依賴關係注入到 Bean 中 * 從命名上可以看出:有 do 這個動作的。因此不是簡單的 get 有就返回,沒有就返回 null 這麼簡單的操作。而是裡面做了例項化、依賴注入、屬性賦值、解決迴圈依賴等一些列操作 */ protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { // 該方法作用: // 1、如果是 FactoryBean,會去掉 Bean 開頭的 & 符號 // 2、能存在傳入別名且別名存在多重對映的情況,這裡會返回最終的名字,如存在多層別名對映 A->B->C->D,傳入 D,最終會返回 A String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // getSingleton() 方法的實現,在父類 DefaultSingletonBeanRegistry 中,請先移步下面,看詳解 // 這裡先嚐試從快取中獲取,若獲取不到,就走下面的建立 // 特別注意的是:這裡面走建立(發現是個new的),就加入進快取裡面了 if (newSingleton) {addSingleton(beanName, singletonObject);} 快取的欄位為全域性的Map:singletonObjects Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { // 這裡雖然只是一句日誌,但是能說明用意。 // 若條件為 true,表示這個 Bean 雖然在快取裡,但是並沒有完全被初始化(迴圈引用) if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } // 在 getBean 方法中,getObjectForBeanInstance 是個頻繁使用的方法。因此為了更好的知道細節,下面會詳解這個方法 // 其實簡單理解就是處理 FactoryBean 的 getObject() 方法 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: We're assumably within a circular reference. // 原型物件不允許迴圈建立,如果是原型物件正在建立,那就拋異常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 這一步也是必須要做的,若存在父容器,得看看父容器是否例項化過它。避免被重複例項化(若父容器被例項化,就以父容器的為準) // 這就是為何,我們掃描 controller,哪怕不加排除什麼的,也不會出問題的原因,因為 Spring 中的單例 Bean 只會被例項化一次(即使父子容器都掃描了) BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } // alreadyCreated 中增加此值。表示此 Bean 已經建立,或正在建立 if (!typeCheckOnly) { // 如果建立 bean 不是為了型別檢查,則要標記當前 bean 已經被建立,或者即將被建立,以便於 BeanFactory 可以優化重複建立的 bean 的快取 markBeanAsCreated(beanName); } try { // 根據名字獲取合併過的對應的 RootBeanDefinition RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 檢查 mbd 是否為抽象的或為單例,但存在 args 的情況(args 只有初始化原型物件才允許存在) checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 這裡很重要,因為 Bean 例項化會有屬性注入等,所以這裡就是要保證它依賴的那些屬性先初始化 // 這部分是處理迴圈依賴的核心,@DependsOn 註解可以控制 Bean 的初始化順序 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { // 迴圈依賴檢查 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } // 將依賴的關係放入快取,以便於當前 bean 銷燬時先銷燬依賴的 bean registerDependentBean(dep, beanName); try { // 先建立依賴的 bean getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. // 從這裡開始,就正式著手建立這個 Bean 例項 if (mbd.isSingleton()) { // 單例模式 // 嘗試從快取中載入單例 Bean,獲取失敗就通過 ObjectFactory 的 createBean 方法建立 // 這個 getSingleton 方法和上面是過載方法,它支援通過 ObjectFactory 去根據 Scope 來建立物件,具體原始碼解析見下面 sharedInstance = getSingleton(beanName, () -> { try { // 這是建立 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. // 執行失敗,就銷燬 Bean。然後執行對應的 destroy 方法等 destroySingleton(beanName); throw ex; } }); // 同樣的工廠型別 Bean 的處理 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // 原型模式 // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); // 原型 Bean 建立的前置處理,記錄當前 Bean 處於正在建立的狀態 prototypeInstance = createBean(beanName, mbd, args); // 原型模式建立 Bean } finally { afterPrototypeCreation(beanName); // 原型 Bean 建立後置處理,移除正在建立狀態,即當前 Bean 已建立完成 } // 同樣的工廠型別 Bean 的處理 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { // 其它 scope 型別的處理 String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'"); } 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); // 使用原型 Bean 的前置處理 try { return createBean(beanName, mbd, args); // 其它 Scope 模式建立 Bean } finally { afterPrototypeCreation(beanName); // 使用原型 Bean 的後置處理 } }); // 同樣的工廠型別 Bean 的處理 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; } } // Check if required type matches the type of the actual bean instance. // 這裡就比較簡單了,就是 requiredType,比如要求是 Integer,獲得的是 String,那麼就會呼叫轉換器轉換過來,絕大多數情況下,沒什麼用 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.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
DefaultSingletonBeanRegistry#getSingleton()
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { @Override @Nullable public Object getSingleton(String beanName) { // 嘗試從快取中獲取,true 為允許提前依賴 return getSingleton(beanName, true); } @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // Quick check for existing instance without full singleton lock // 此處是先從已經快取好了的 singletonObjects 的 Map 中,檢視有木有(至於當前已經有哪些了,開頭有個截圖) Object singletonObject = this.singletonObjects.get(beanName); // 若快取裡沒有。並且這個 Bean 必須在建立中,才會進來。 // singletonsCurrentlyInCreation 欄位含義:會快取下來所有的正在建立中的 Bean,如果有 Bean 是迴圈引用的,會把這種 Bean 先放進去,這裡才會有值 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 從提前載入的 bean 的快取集合中獲取 singletonObject = this.earlySingletonObjects.get(beanName); // 如果為空並且允許提前依賴 if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { // Consistent creation of early reference within full singleton lock singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { // 從快取中獲取 Bean 的工廠 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 如果工廠不為空,則呼叫工廠方法載入 Bean singletonObject = singletonFactory.getObject(); // 記錄到提前載入的 Bean 的快取中 this.earlySingletonObjects.put(beanName, singletonObject); // 已經呼叫工廠載入 Bean,將工廠從快取中移除,無需再次載入 this.singletonFactories.remove(beanName); } } } } } } return singletonObject; }
DefaultSingletonBeanRegistry#getSingleton(根據 ObjectFactory 結合 Scope 來建立合適的物件)
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { // 從快取中獲取(上面獲取過一次的,這裡是雙重判定) Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { // 如果這個 Bean 正在被銷燬,就拋異常 if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } // 單例 Bean 建立的前置檢查: // 1、是否在 inCreationCheckExclusions 校驗名單裡 // 2、singletonsCurrentlyInCreation 把它新增進去,證明這個 Bean 正在建立中 beforeSingletonCreation(beanName); // 此處先打標記為 false boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { // 把這個例項生成出來,並且標誌位設為 true singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> if yes, proceed with it since the exception indicates that state. // 在此期間,若已經把這個 Bean 放進去了,就丟擲異常 singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { // 處理異常 // 比如我們經常遇到的 UnsatisfiedDependencyException 異常:@Autowired 的時候找不到依賴的 Bean 就是這個異常(一般由 NoSuchBeanDefinitionException 這個異常導致) // 這裡會把異常連結拼接起來,然後一起打印出來,非常方便查詢問題 if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } // 建立完成後再檢查一遍。做的操作為:從正在建立快取中移除 afterSingletonCreation(beanName); } // 這裡非常重要:若是新的 Bean,那就執行 addSingleton 這個方法,為下面 4 步操作: // this.singletonObjects.put(beanName, singletonObject); // 快取起來 // this.singletonFactories.remove(beanName); // 把對應 ObjectFactory 的快取移除 // this.earlySingletonObjects.remove(beanName); // this.registeredSingletons.add(beanName); if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
getObjectForBeanInstance
在 doGetBean 中不論是什麼方式獲得的 Bean,都會執行 getObjectForBeanInstance 方法。原因是,不論哪種方式獲得的 Bean 都是原始的狀態,並不是我們真正想要的 Bean。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { /** * Cache of singleton objects: bean name to bean instance. 一級 Cache:單例物件 */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /** * Cache of singleton factories: bean name to ObjectFactory. 三級 Cache:單例物件的工廠 */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** * Cache of early singleton objects: bean name to bean instance. 二級 Cache:提前曝光的單例物件 * 與一級 Cache:singletonFactories 區別在於 earlySingletonObjects 中存放的 bean 不一定是完整的,這個 Map 也是【迴圈依賴】的關鍵 */ private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { @Override protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { String currentlyCreatedBean = this.currentlyCreatedBean.get(); if (currentlyCreatedBean != null) { // 如果 Bean 正在被建立,就註冊這個 Bean 所依賴的 Bean,這樣當這個 Bean 被銷燬時,同時銷燬這些依賴的 Bean registerDependentBean(beanName, currentlyCreatedBean); } return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd); } public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. if (BeanFactoryUtils.isFactoryDereference(name)) { // 如果 name 是工廠類的引用名稱(name 以 "&" 開頭) if (beanInstance instanceof NullBean) { // 如果是 NullBean 則直接返回 return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { // 如果 beanInstance 不是 FactoryBean 則丟擲異常 throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } if (mbd != null) { mbd.isFactoryBean = true; } return beanInstance; } // Now we have the bean instance, which may be a normal bean or a FactoryBean. If it's a FactoryBean, we use it to create a bean instance, unless the caller actually wants a reference to the factory. // 走到這裡,說明現在已經有一個 Bean 例項,該例項可能是一個正常的 Bean 又或者是一個 FactoryBean // 如果 beanInstance 不是 Factory,則直接返回 if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } Object object = null; if (mbd != null) { mbd.isFactoryBean = true; } else { // 若 BeanDefinition 為 null,則從快取中載入 Bean 物件 object = getCachedObjectForFactoryBean(beanName); } // 如果 Object 為 null,則可以確認 beanInstance 一定是 FactoryBean。從而使用 FactoryBean 獲取 Bean 物件 // 通過 beanInstance instanceof FactoryBean 這裡判斷,如果 beanInstance 不是 FactoryBean 已經直接返回了 if (object == null) { // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. // 檢測 beanDefinitionMap 中,也就是所有已載入的類中是否定義了 beanName if (mbd == null && containsBeanDefinition(beanName)) { // 將儲存 XML 配置檔案的 GenericBeanDefinition 轉換為 RootBeanDefinition // 如果指定 beanName 是子類 Bean 的話,會同時合併父類的相關屬性 mbd = getMergedLocalBeanDefinition(beanName); } // 是否是使用者定義的,而不是程式本身定義的 boolean synthetic = (mbd != null && mbd.isSynthetic()); // 核心函式,使用 FactoryBean 獲得 Bean 物件 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; } public abstract class FactoryBeanRegistrySupport extends org.springframework.beans.factory.support.DefaultSingletonBeanRegistry { protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) { // 單例,且快取中存在該 Bean 例項 synchronized (getSingletonMutex()) { // 從快取中獲取指定的 FactoryBean Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { // 為 null,則從 FactoryBean 中獲取 Bean object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above (e.g. because of circular reference processing triggered by custom getBean calls) // 再次從快取中獲取 Bean 物件,主要是因為自定義的 bean 呼叫處理迴圈依賴時可能已經放入快取 Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; // 獲取快取中的 } else { if (shouldPostProcess) { // 需要後續處理 if (isSingletonCurrentlyInCreation(beanName)) { // 如果該 Bean 處於建立中,則返回非未處理的物件(尚未儲存該物件) // Temporarily return non-post-processed object, not storing it yet.. return object; } // 單例 Bean 建立的前置處理。用於新增標誌,表示當前 Bean 正處於建立中 beforeSingletonCreation(beanName); try { // 對 FactoryBean 獲取的物件進行後置處理,也就是 BeanPostProcessor 的呼叫 object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { // 單例 Bean 建立的後置處理。用於移除標誌,表示當前 Bean 不處於建立中 afterSingletonCreation(beanName); } } // 新增到 factoryBeanObjectCache 中進行快取 if (containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } else { // 非單例,或者快取中不存在 Object object = doGetObjectFromFactoryBean(factory, beanName); // 從 FactoryBean 中獲取物件 if (shouldPostProcess) { // 需要後續處理 try { // 對 FactoryBean 獲取的物件進行後處理,也就是 BeanPostProcessor 的呼叫 object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } } private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 呼叫 getObject 方法獲取 Bean object = factory.getObject(); } } catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex); } // Do not accept a null value for a FactoryBean that's not fully initialized yet: Many FactoryBeans just return null then. if (object == null) { if (isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject"); } object = new NullBean(); } return object; }
doGetBean() 中建立 Bean 邏輯呼叫的是AbstractAutowireCapableBeanFactory#createBean()
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { @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. // 確保對應 BeanClass 完成解析(已經載入進來了 Class 物件)具體表現是進行了 ClassLoder.loadClass 或 Class.forName 完成了類載入 // 主要根據傳入的 typesToMatch 生成特定 的ClassLoader,之後還要呼叫 RootBeanDefinition#resolveBeanClass,根據特定的載入器或者預設載入器加載出 class 屬性對應的 Class 物件 // 判斷需要建立的 Bean 是否可以例項化,這個類是否可以通過類裝載器來載入(也就說它甚至可能來源於網路) Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { // 這裡主要是解析 <lookup-method name="getFruit" bean="bananer"/> 類似這種方式的依賴注入(Spring 支援 lookup-method,replace-method 兩個依賴注入的方式) // 它相當於呼叫指定類裡面的指定方法進行注入,所以需要考慮到方法過載的情況,因此這個方法解析的就是這種情況 // 專案中一般這麼使用,非常的不大眾,具體原理此處省略 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. // 從 doc 解釋:給 BeanPostProcessors 一個機會來返回一個代理物件代替目標物件,什麼動態代理之類的,都在這裡實現的 // 1、判斷當前 Spring 容器是否註冊了實現了 InstantiationAwareBeanPostProcessor 介面的後置處理器,如果有,則依次呼叫其中的 applyBeanPostProcessorsBeforeInstantiation 方法,中間任意一個方法返回不為 null,直接結束呼叫 // 2、依次呼叫所有的 BeanPostProcessor#postProcessAfterInitialization 方法(如果任意一次返回不為 null,終止呼叫) // 這個方法也非常的重要 // 容器裡所有的 InstantiationAwareBeanPostProcessors 例項,都會在此處生效,進行前置處理 // 下面有解釋:BeanPostProcessor 和 InstantiationAwareBeanPostProcessor 的區別,可以分清楚它們執行的時機 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 { // 這裡是重點:doCreateBean 建立 Bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } // 建立完成後,直接返回 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); } } @Nullable protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; // beforeInstantiationResolved 這個屬性如果是 false,表示不需要被前置處理了 // 然後,唯一能改變它的值的地方,是下面這僅僅一行程式碼而已,它的訪問許可權為 package if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. // 這裡 hasInstantiationAwareBeanPostProcessors() 方法就是看屬性 hasInstantiationAwareBeanPostProcessors 的值。就是標記容器裡是否有 InstantiationAwareBeanPostProcessor 的實現 // 顯然,在執行 addBeanPostProcessor,發現這個 Bean 是這個子型別的時候,就會設為 true 了。同理的還有 hasDestructionAwareBeanPostProcessors 這個屬性,表示銷燬的處理器 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // 拿到最終的目標型別(放置被別的包裝過) // 可能依賴於 AbstractBeanFactory#resolveBeanClass 這個方法去解析 Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { // 先執行執行 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 回撥方法 // 裡面的邏輯也比較簡單:拿到快取好的(List)所有 BeanPostProcessors,如果是 InstantiationAwareBeanPostProcessor 就執行 // 只要有一個 result 不為 null,後面的所有後置處理器的方法就不執行了,直接返回(所以執行順序很重要) // 1、ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor 這個內部類就是這個型別。主要是增強、完善處理 @Configuration 這種類,但它並沒有重寫 postProcessBeforeInstantiation 方法,所以預設是返回 null // 2、CommonAnnotationBeanPostProcessor/Autowired...也沒做處理(若你自己不去註冊,那系統裡就再沒有了) // 需要注意的是,如果我們採用了 AOP、宣告式事務等,這裡就會有了 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); // 如果 Bean 不為 null,那就直接返回了,不執行後面的 After 了 if (bean != null) { // 注意,這裡是 Initialization,是初始化的後置方法,是 BeanPostProcessor 的方法,也就是說初始化完成後的方法。 // 為何這裡執行這個方法呢?是因為我們上面說了,如果返回不為 null,後面都都會被短路掉。但是此處 Spring 還是讓我們執行了初始化後的處理器方法,這點需要引起注意 // 就是說:即使 Bean 在例項化前已經返回了一個不為 null 的物件,別的方法都被短路了,但是我的【初始化】後置處理器方法 applyBeanPostProcessorsAfterInitializationh 還是可以執行的 // 這裡面可以關注一下這個類:ApplicationListenerDetector // 初始化之後的方法返回了 null,那就需要呼叫 doCreateBean 生成物件了 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
這一步中的幾個介面
public interface BeanPostProcessor { /** * Bean 初始化前,一般是在呼叫 init-method 前,例項化早於初始化 * 初始化:在目標物件被例項化之後,並且屬性也被設定之後呼叫 */ @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * Bean 初始化後 */ @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { /** * Bean 例項化前 * 例項化:一個建立 Bean 的過程,即呼叫 Bean 的建構函式及 Bean 的屬性設定,單例 Bean 放入單例池中 * 返回值型別為 Object,由於這個時候目標物件還未例項化,所以可以返回其它例項(比如代理物件)。 * 如果該方法的返回值代替原本該生成的目標物件,後續就只有 postProcessAfterInitialization 方法會呼叫,其它方法不再呼叫。否則按照正常的流程走 */ @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } /** * Bean 例項化後 * 這個時候物件已經被例項化,但是該例項的屬性還未被設定,都是 null。因為它的返回值是決定要不要呼叫 postProcessPropertyValues 方法的其中一個因素(因為還有一個因素是 mbd.getDependencyCheck()) * 如果該方法返回 false,並且不需要 check,那麼 postProcessPropertyValues 就會被忽略不執行。如果返回 true,postProcessPropertyValues 就會被執行 */ default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } /** * 已經過時,由上面的 postProcessProperties 代替 * 對屬性值進行修改(這個時候屬性值還未被設定,但是我們可以修改原本該設定進去的屬性值)。如果 postProcessAfterInstantiation 方法返回 false,該方法可能不會被呼叫 */ @Deprecated @Nullable default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } } public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor { /** * 預測 Bean 的型別,返回第一個預測成功的 Class 型別,如果不能預測則返回 null */ @Nullable default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException { return null; } /** * 若目標物件有多個構造器,在這裡可以進行一些定製化,選擇合適的構造器 * beanClass 引數表示目標例項的型別,beanName 是目標例項在 Spring 容器中的 name * 返回值是個構造器陣列,如果返回 null,會執行下一個 PostProcessor 的 determineCandidateConstructors 方法;否則選取該 PostProcessor 選擇的構造器 * Spring4.0 之後可以泛型依賴注入: * @Autowired private BaseRepository<Student> studentRepo; * @Autowired private BaseRepository<Faculty> facultyRepo; */ @Nullable default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException { return null; } /** * 獲得提前暴露的 Bean 引用。主要用於解決迴圈引用的問題 * 只有單例物件才會呼叫此方法,在處理迴圈引用的時候,這個方法會起到比較關鍵的作用 */ default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; } } public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor { /** * 給後續回撥中快取一些 meta 資訊 */ void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName); default void resetBeanDefinition(String beanName) { } }
createBean() 呼叫的 doCreateBean()
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; // 用 BeanWrapper 來持有創建出來的 Bean 物件 if (mbd.isSingleton()) { // 如果是單例的話,先把快取中的同名 Bean 清除 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } // 實際建立的交給 createBeanInstance 來完成,Bean 的生成,這裡會使用預設的類生成器,包裝成 BeanWrapperImpl 類,為了下面的 populateBean 方法的屬性注入做準備 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); // 如果不是 NullBean,則將 resolvedTargetType 屬性設定為當前的 WrappedClass if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 此處處理 MergedBeanDefinitionPostProcessor 介面的處理器,它在 BeanPostProcessor 的基礎上增加了 postProcessMergedBeanDefinition 方法,在此處就被呼叫了 // 主要是處理 @PostConstruct、@Autowire、@Value、@Resource、@PreDestory 等這些註解 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references even when triggered by lifecycle interfaces like BeanFactoryAware. // 如果當前 Bean 是單例,且支援迴圈依賴,且當前 Bean 正在建立,通過往 singletonFactories 新增一個 objectFactory,這樣後期如果有其它 Bean 依賴該 Bean,可以從 singletonFactories 獲取到 Bean // getEarlyBeanReference 可以對返回的 Bean 進行修改,這邊目前除了可能會返回動態代理物件 其它的都是直接返回 Bean boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 這裡面主要是解決迴圈引用問題,藉助了這個工廠 // 主要是呼叫處理器:SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference 方法去找到前期的 Bean(若存在這種處理器的話) addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; // 這個 Obj,就是最終要返回的物件 try { // 非常重要的一步:給已經初始化的屬性們賦值,對 Bean 進行填充,在這裡面完成依賴注入的相關內容 populateBean(beanName, mbd, instanceWrapper); // 完成屬性依賴注入後,進一步初始化 Bean,具體進行了以下操作: // 若實現了 BeanNameAware、BeanClassLoaderAware、BeanFactoryAwareAware 等介面,則注入相關物件 // 遍歷後置處理器,呼叫實現的 postProcessBeforeInitialization 方法 // 如果實現了 initialzingBean,呼叫實現的 afterPropertiesSet() // 如果配置了 init-mothod,呼叫相應的 init 方法 // 遍歷後置處理器,呼叫實現的 postProcessAfterInitialization 方法 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); } } // 如果 earlySingletonExposure 為 true,嘗試從快取獲取該 Bean(一般存放在 singletonFactories 物件,通過呼叫 getObject 把物件存入 earlySingletonObjects), // 分別從 singletonObjects 和 earlySingletonObjects 獲取物件,這裡依然是處理迴圈依賴相關問題的 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 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 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { // 如果有需要,就註冊 DisposableBean,這樣 Bean 銷燬的時候,這種後置處理器也會生效了 registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. // 確保 Bean 類已經解析過了,可以例項化 Class<?> beanClass = resolveBeanClass(mbd, beanName); // 確保 class 不為空,並且訪問許可權為 public,所以注意如果你的 Class 不是 public 的,Spring 給你建立不了物件 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()); } // 配置的一種特殊的 callback 回撥方法,通過這個 callback 建立 Bean // Supplier 返回的 Obj,最終會交給 obtainFromSupplier 包裝成 BeanWrapper Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } // 這是 Spring 支援的又一種方式:使用工廠方法來進行 Bean 的例項化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... // 一個類可能有多個構造器,所以 Spring 得根據引數個數、型別確定需要呼叫的構造器 // 在使用構造器建立例項後,Spring 會將解析過後確定下來的構造器或工廠方法儲存在快取中,避免再次建立相同 Bean 時再次解析 boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { // 標記一下,已經解析過 class 的構造器 resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { // resolved 若為 true,表示已經解析過構造器了,就下面直接使用解析好的構造器例項化 Bean if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } // Candidate constructors for autowiring? // 通過此方法,去檢測可用的構造器:這裡使用 SmartInstantiationAwareBeanPostProcessor,它通過迴圈呼叫處理器的 determineCandidateConstructors 方法,誰第一個發現一個可用的構造器,就 return,否則返回 null // 這裡需要注意:如果 Bean 沒有空的建構函式(比如只有一個引數的建構函式,那麼 Spring 會用這個建構函式例項化 Bean,並且入參會自動從容器裡去找出來) Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // ctors 不為 null,或者標註了處理機制是構造器注入方式,AbstractBeanDefinition#setAutowireMode 可以設定模式 if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { // 構造器選擇策略,自動注入 return autowireConstructor(beanName, mbd, ctors, args); } // Preferred constructors for default construction? ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } // No special handling: simply use no-arg constructor. 使用無參構造器初始化 return instantiateBean(beanName, mbd); }
determineConstructorsFromBeanPostProcessors()
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { @Nullable protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException { if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName); if (ctors != null) { return ctors; } } } } return null; } public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { @Override @Nullable public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException { // Let's check for lookup methods here... // 檢測 @Lookup 註解,這個註解的注入方式,已經不推薦使用了 if (!this.lookupMethodsChecked.contains(beanName)) { if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) { try { Class<?> targetClass = beanClass; do { ReflectionUtils.doWithLocalMethods(targetClass, method -> { Lookup lookup = method.getAnnotation(Lookup.class); if (lookup != null) { Assert.state(this.beanFactory != null, "No BeanFactory available"); LookupOverride override = new LookupOverride(method, lookup.value()); try { RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName); mbd.getMethodOverrides().addOverride(override); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition"); } } }); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Lookup method resolution failed", ex); } } this.lookupMethodsChecked.add(beanName); } // Quick check on the concurrent map first, with minimal locking. // 先從快取裡去看,有沒有解析過此類的建構函式,對每個類的建構函式只解析一次,解析完會儲存結果,以備下次複用 Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { // Fully synchronized resolution now... synchronized (this.candidateConstructorsCache) { // 為了執行緒安全,這裡繼續校驗一次 candidateConstructors = this.candidateConstructorsCache.get(beanClass); if (candidateConstructors == null) { Constructor<?>[] rawCandidates; try { // 拿到此 Class 所有的建構函式(一般的類都只有一個空的建構函式),當然也可以寫多個 rawCandidates = beanClass.getDeclaredConstructors(); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex); } List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length); Constructor<?> requiredConstructor = null; Constructor<?> defaultConstructor = null; // 相容 Kotlin 型別做的處理 Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass); int nonSyntheticConstructors = 0; for (Constructor<?> candidate : rawCandidates) { // 遍歷處理構造器 if (!candidate.isSynthetic()) { nonSyntheticConstructors++; } else if (primaryConstructor != null) { continue; } // 找到構造器裡有 @Aotowaired 或者 @Value 註解的直接資訊 MergedAnnotation<?> ann = findAutowiredAnnotation(candidate); if (ann == null) { // 此方法的目是拿到目標類:比如若是被 cglib 代理過的,那就拿到父類(因為 cglib 是通過子類的形式加強的) Class<?> userClass = ClassUtils.getUserClass(beanClass); if (userClass != beanClass) { // 確實是被 CGLIB 代理過的,那就再解析一次,看看父類是否有 @Autowaired 這種構造器 try { Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes()); ann = findAutowiredAnnotation(superCtor); } catch (NoSuchMethodException ex) { // Simply proceed, no equivalent superclass constructor found... } } } if (ann != null) { // 存在註解標註的這種構造器 // 這個判斷很有必要,表示要求的構造器最多隻能有一個 // 注:@Autowired 標註的構造器數量最多隻能有一個(當然,required=true 的只能有一個,=false 的可以有多個) if (requiredConstructor != null) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor); } // 獲取 Autowire 註解中 required 屬性值 boolean required = determineRequiredStatus(ann); if (required) { // 只有是 true 才往下走(預設值為 true) if (!candidates.isEmpty()) { throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + ". Found constructor with 'required' Autowired annotation: " + candidate); } // 這樣子,這個構造器就是必須的了,記錄下來 requiredConstructor = candidate; } // 把標註有 @Autowired 註解的構造器,記錄下來,作為候選的構造器 candidates.add(candidate); } else if (candidate.getParameterCount() == 0) { // 這個就重要了,若該構造器沒有被標註 @Autowired 註解,但是它是無參構造器,那就當選的構造器(當然是以標註了 @Autowired 的為準) // 注意:雖然把預設的建構函式記錄下來了,但是並沒有加進 candidates 裡 defaultConstructor = candidate; } } if (!candidates.isEmpty()) { // 若能找到候選的構造器 // Add default constructor to list of optional constructors, as fallback. if (requiredConstructor == null) { if (defaultConstructor != null) { candidates.add(defaultConstructor); } else if (candidates.size() == 1 && logger.isInfoEnabled()) { // 如果沒有預設的無參建構函式,且有 @Autowired(required = false)的建構函式,則發出警告 logger.info("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - " + "this constructor is effectively required since there is no " + "default constructor to fall back to: " + candidates.get(0)); } } candidateConstructors = candidates.toArray(new Constructor<?>[0]); } else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) { // 有且僅有一個構造器,並且該構造器的引數大於 0 個,那就是我們要找的構造器了,這種情況,也是平時我們使用得比較多的情況 candidateConstructors = new Constructor<?>[]{rawCandidates[0]}; } else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) { // 處理 primaryConstructor 以及 nonSyntheticConstructors,相容 Kotlin 一般都達不到 candidateConstructors = new Constructor<?>[]{primaryConstructor, defaultConstructor}; } else if (nonSyntheticConstructors == 1 && primaryConstructor != null) { candidateConstructors = new Constructor<?>[]{primaryConstructor}; } else { // 啥構造器都沒找到,那就是空陣列 candidateConstructors = new Constructor<?>[0]; } this.candidateConstructorsCache.put(beanClass, candidateConstructors); } } } // 若有多個建構函式,但是沒有一個標記了 @Autowired,此處不會報錯,但是返回 null,交給後面的策略處理 return (candidateConstructors.length > 0 ? candidateConstructors : null); } }
autowireConstructor()
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) { // 此處的 this,就是 DefaultListableBeanFactory return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs); } class ConstructorResolver { public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) { // 先例項化一個 BeanWrapperImpl 類物件 BeanWrapperImpl bw = new BeanWrapperImpl(); // initBeanWrapper 做了一些事,比如註冊解析器、value 解析器等 this.beanFactory.initBeanWrapper(bw); Constructor<?> constructorToUse = null; ArgumentsHolder argsHolderToUse = null; Object[] argsToUse = null; if (explicitArgs != null) { // 如果構造引數不為空,就直接使用這些引數 argsToUse = explicitArgs; } else { // 否則建構函式的入參,交給 Spring 處理。它會去容器裡拿 Object[] argsToResolve = null; synchronized (mbd.constructorArgumentLock) { // 獲取已快取解析的建構函式或工廠方法(resolvedConstructorOrFactoryMethod 用於快取已解析的建構函式或工廠方法) // 如果快取不為空,並且構造引數已經解析快取了,(constructorArgumentsResolved 為包可見,用於表示構造引數狀態是否已經解析) // 顯然首次進來,都是為 null,並且沒有被解析 constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod; if (constructorToUse != null && mbd.constructorArgumentsResolved) { // Found a cached constructor... argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null) { // 如果上面沒有解析過,顯然這裡引數就是 null 了,argsToUse 也就還為 null,Spring 下面繼續解析 argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true); } } if (constructorToUse == null || argsToUse == null) { // 如果快取的構造器不存在,就說明沒有 Bean 進行過解析,需要去關聯對應的 Bean 的構造器 // Take specified constructors, if any. // 如果傳入的構造器為空,則獲取 bean 的 Class 物件,然後根據 bean 是不是 public 修飾的來按照不同的方式獲取所有的構造器 // 顯然,我們這裡(大都都會有構造器) // 但是此處我們發現,即使構造器不是 public 的,這裡也能夠遭到構造器來進行例項化 Constructor<?>[] candidates = chosenCtors; if (candidates == null) { Class<?> beanClass = mbd.getBeanClass(); try { // getDeclaredConstructors 返回所有的構造器(包括 public 和 private 修飾的),getConstructors 返回 public 修飾的 candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors()); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex); } } if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) { Constructor<?> uniqueCandidate = candidates[0]; if (uniqueCandidate.getParameterCount() == 0) { synchronized (mbd.constructorArgumentLock) { mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate; mbd.constructorArgumentsResolved = true; mbd.resolvedConstructorArguments = EMPTY_ARGS; } bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS)); return bw; } } // Need to resolve the constructor. // 我們的傳值 chosenCtors 顯然不為 null,所以此值為 true boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null; int minNrOfArgs; if (explicitArgs != null) { // 若傳入的構造引數不為空,那最小引數長度以它為準 minNrOfArgs = explicitArgs.length; } else { // 這裡相當於要解析出建構函式的引數了,解析對應的構造引數然後新增到 ConstructorArgumentValues 中 ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } // 構造器排序,按照訪問方式和數量對構造器進行排序;public > protect > private,在同為 public 時構造器入參多的排在前面 // 所以排在第一位的,是 public 的,引數最多的構造器 AutowireUtils.sortConstructors(candidates); int minTypeDiffWeight = Integer.MAX_VALUE; // 記錄下,引起歧義的構造器們。就是記錄下來,如果存在這種歧義,拋異常的時候用來告訴呼叫者 Set<Constructor<?>> ambiguousConstructors = null; LinkedList<UnsatisfiedDependencyException> causes = null; // 開始遍歷排序後的構造器了 for (Constructor<?> candidate : candidates) { // 拿到構造器引數的型別們 int parameterCount = candidate.getParameterCount(); // constructorToUse 不為 null(表示已經找到了合適構造器),但是呢,連引數個數的長度都對應不上,那就直接 break,後面的構造器全都不用看了 if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) { // Already found greedy constructor that can be satisfied -> do not look any further, there are only less greedy constructors left. break; } // 如果引數個數比最小個數還小,那就繼續下一個構造器吧。 if (parameterCount < minNrOfArgs) { continue; } ArgumentsHolder argsHolder; Class<?>[] paramTypes = candidate.getParameterTypes(); if (resolvedValues != null) { try { // 相容 JDK6 提供的 @ConstructorProperties 這個註解,如果它標註了引數名,那就以它的名字為準 // @ConstructorProperties 的作用:建構函式上的註解,顯示該建構函式的引數如何與構造物件的 getter 方法相對應 String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount); if (paramNames == null) { // 否則,就自己解析 // 一般都是 Bean 工廠預設的 DefaultParameterNameDiscoverer 解析出變數名 ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); if (pnd != null) { paramNames = pnd.getParameterNames(candidate); } } // 根據獲取到的引數名和已經查到的構造引數和構造引數型別來建立使用者建立構造器用的構造引數陣列 // 這個陣列中包含了原始的引數列表和構造後的引數列表,用來對比用 argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1); } catch (UnsatisfiedDependencyException ex) { if (logger.isTraceEnabled()) { logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex); } // Swallow and try next constructor. if (causes == null) { causes = new LinkedList<>(); } causes.add(ex); continue; } } else { // Explicit arguments given -> arguments length must match exactly. if (parameterCount != explicitArgs.length) { continue; } argsHolder = new org.springframework.beans.factory.support.ConstructorResolver.ArgumentsHolder(explicitArgs); } // lenientConstructorResolution 的值 ture 與 false 區別: // 預設 true,在大部分情況下都是使用[寬鬆模式],即使多個建構函式的引數數量相同、型別存在父子類、介面實現類關係也能正常建立 Bean // false 表示嚴格模式。與上面相反 // typeDiffWeight:返回不同的個數的權重 int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); // Choose this constructor if it represents the closest match. if (typeDiffWeight < minTypeDiffWeight) { // 根據權重,選擇一個最為合適的構造器 // 大都進這裡來,然後是沒有 ambiguousConstructors 的 constructorToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousConstructors = null; } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { if (ambiguousConstructors == null) { ambiguousConstructors = new LinkedHashSet<>(); ambiguousConstructors.add(constructorToUse); } ambiguousConstructors.add(candidate); } } // 如果此時還沒發現可用的構造器,那這裡就開始處理異常 if (constructorToUse == null) { if (causes != null) { UnsatisfiedDependencyException ex = causes.removeLast(); for (Exception cause : causes) { this.beanFactory.onSuppressedException(cause); } throw ex; } throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Could not resolve matching constructor " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)"); } else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Ambiguous constructor matches found in bean '" + beanName + "' " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + ambiguousConstructors); } if (explicitArgs == null && argsHolderToUse != null) { argsHolderToUse.storeCache(mbd, constructorToUse); } } Assert.state(argsToUse != null, "Unresolved constructor arguments"); // 下面步驟都是通用的,用上面得到的構造器(無論是從 Bean 物件中獲取的還是 Spring 自己構建的)和引數來反射建立 Bean 例項,並放到 BeanWrapperImpl 物件中然後返回 bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse)); return bw; } private Object instantiate(String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) { try { // 拿到生成 Bean 例項化策略,預設值為 CglibSubclassingInstantiationStrategy 用 CGLIB 生成子類的方式 InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy(); if (System.getSecurityManager() != null) { return AccessController.doPrivileged((PrivilegedAction<Object>) () -> strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse), this.beanFactory.getAccessControlContext()); } else { // 主要就是呼叫了策略器的 instantiate,對 Bean 進行了最終的例項化 // 此方法為過載方法,此處因為不需要代理,所以執行的直接是 SimpleInstantiationStrategy#instantiate // 到此處,Bean 正式建立,然後繼續到 doCreateBean 方法 return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse); } } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean instantiation via constructor failed", ex); } }
doCreateBean() 呼叫了populateBean() 和initializeBean()
populateBean 做 Bean 屬性賦值操作(依賴注入)
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { // 在完成 Bean 例項化後,Spring 容器會給這個 Bean 注入相關的依賴 Bean protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 對例項 Bean 的判空校驗 if (bw == null) { 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; } } // 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. // 給 InstantiationAwareBeanPostProcessors 最後一次機會,在屬性注入前修改 Bean 的屬性值 // 具體通過呼叫 postProcessAfterInstantiation 方法,如果呼叫返回 false,表示不必繼續進行依賴注入,直接返回 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // postProcessAfterInstantiation 這個方法返回 true,後面的處理器才會繼續執行,返回 false,後面的就不會再執行了 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // pvs 是一個 MutablePropertyValues 例項,裡面實現了 PropertyValues 介面,提供屬性的讀寫操作實現,同時可以通過呼叫建構函式實現深拷貝 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // 根據 Bean 配置的依賴注入方式完成注入,預設是 0,即不走以下邏輯,所有的依賴注入都需要在 xml(或者 @Bean 中)檔案中有顯式的配置 // 如果設定了相關的依賴裝配方式,會遍歷 Bean 中的屬性,根據型別或名稱來完成相應注入,無需額外配置 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { // 深拷貝當前已有的配置 MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); // 根據名稱進行注入 } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); // 根據型別進行注入 } // 結合注入後的配置,覆蓋當前配置 pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 是否進行依賴檢查,預設值就是 None,所以此處返回 false,表示不需要依賴檢查(關於依賴檢查的 4 種模式,建議使用 @Required 來顯示控制) // @Required 註解作用於 Bean setter 方法上,用於檢查一個 Bean 的屬性的值在配置期間是否被賦予或設定(populated) boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } // 在這呼叫了 InstantiationAwareBeanPostProcessor#postProcessPropertyValues 方法,若返回 null,整個 populateBean 方法就結束了 for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // 關於 postProcessPropertyValues 的實現,有幾個處理器是非常關鍵的: // 比如 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor 等 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); // 若返回 null,Spring 表示你已經屬性值都設定好了,那它也不再管了 if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { // 過濾出所有需要進行依賴檢查的屬性編輯器 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } // 將 pvs 上所有的屬性填充到 BeanWrapper 對應的 Bean 例項中 // 注意:這一步完成結束後為止。我們的 Bean 依賴的 parent,還只是 RuntimeBeanReference 型別,還並不是真實的 Parent 這個 Bean // 在 Spring 的解析段,其它容器中是沒有依賴的 Bean 的例項的,因此這個被依賴的 Bean 需要表示成 RuntimeBeanReferenc 物件,並將它放到 BeanDefinition 的 MutablePropertyValues 中。 if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } } protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 根據 bw 的 PropertyDescriptors,遍歷出所有可寫的(即 set 方法存在),存在於 BeanDefinition 裡的 PropertyValues,且不是簡單屬性的屬性名 // 簡單屬性的判定參照下面方法,主要涵蓋基本型別及其包裝類,Number、Date 等 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { // 再說明一下 containsLocalBean 這個方法,和 containsBean 的區別在於它只在自己的容器裡找,不去父容器裡找,其餘的一樣 if (containsBean(propertyName)) { // 注意:此處找到依賴了,呼叫了 getBean(),所以即使現在僅僅只是 Bean 定義,那麼會被建立例項物件 Object bean = getBean(propertyName); pvs.add(propertyName, bean); // 註冊依賴關係 // 此處需要知道的是:Spring 中使用 dependentBeanMap 和 dependenciesForBeanMap 來管理這些 Bean 的依賴關係: // Map<String, Set<String>> dependentBeanMap:存放當前 Bean 被引用的 Bean 的集合 // Map<String, Set<String>> dependenciesForBeanMap:存放當前 Bean 所依賴的 Bean 的集合 // 依賴注入的具體實現是在 BeanWrapperImpl 類中的 setPropertyValue 方法裡 registerDependentBean(propertyName, beanName); if (logger.isTraceEnabled()) { logger.trace("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { if (logger.isTraceEnabled()) { logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found"); } } } } protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 型別轉換器,如果沒有指定,就用 BeanWrapper 這個轉換器 TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); // Don't try autowiring by type for type Object: never makes sense, // even if it technically is a unsatisfied, non-simple property. // 如果是 Object 型別不進行裝配 if (Object.class != pd.getPropertyType()) { // 獲取相關的寫方法引數 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. // 看看例項是否實現了 PriorityOrdered 介面,若沒有實現,就稍後點載入吧 boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 這裡會根據傳入 desc 裡的入參型別,作為依賴裝配的型別 // 再根據這個型別在 BeanFacoty 中查詢所有類或其父類相同的 BeanName // 最後根據 BeanName 獲取或初始化相應的類,然後將所有滿足條件的 BeanName 填充到 autowiredBeanNames 中 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { pvs.add(propertyName, autowiredArgument); } // 需要注入的依賴都拿到後,就開始註冊這些依賴吧 for (String autowiredBeanName : autowiredBeanNames) { // 註冊這些依賴 registerDependentBean(autowiredBeanName, beanName); if (logger.isTraceEnabled()) { logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'"); } } autowiredBeanNames.clear(); } } catch (BeansException ex) { throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex); } } }
populateBean 中呼叫的一些InstantiationAwareBeanPostProcessor
// 這裡就是解析該 Bean 的 Autowired 資訊,然後給 inject 進去 public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { @Deprecated @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) { return postProcessProperties(pvs, bean, beanName); } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; } // 和 AutowiredAnnotationBeanPostProcessor 一樣,它處理 JSR-250 的註解,如 @Resource public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable { @Deprecated @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) { return postProcessProperties(pvs, bean, beanName); } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex); } return pvs; } // 它就是去校驗,標註了 @Required 註解的,必須是存在這個 Bean 的 // 從 5.1 版開始棄用,建議使用建構函式注入必需的 Bean(或自定義 InitializingBean 的實現) @Deprecated public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) { if (!this.validatedBeanNames.contains(beanName)) { if (!shouldSkip(this.beanFactory, beanName)) { List<String> invalidProperties = new ArrayList<>(); for (PropertyDescriptor pd : pds) { if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) { invalidProperties.add(pd.getName()); } } if (!invalidProperties.isEmpty()) { throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName)); } } this.validatedBeanNames.add(beanName); } return pvs; }
InjectionMetadata#inject 處理依賴注入,實現為AutowiredAnnotationBeanPostProcessor 的內部類
public class InjectionMetadata { public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Collection<InjectedElement> checkedElements = this.checkedElements; Collection<InjectedElement> elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements); if (!elementsToIterate.isEmpty()) { for (InjectedElement element : elementsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean '" + beanName + "': " + element); } // 主要的方法,還是在 InjectedElement#inject 裡 element.inject(target, beanName, pvs); } } } public abstract static class InjectedElement { protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable { if (this.isField) { Field field = (Field) this.member; ReflectionUtils.makeAccessible(field); field.set(target, getResourceToInject(target, requestingBeanName)); } else { if (checkPropertySkipping(pvs)) { return; } try { Method method = (Method) this.member; ReflectionUtils.makeAccessible(method); method.invoke(target, getResourceToInject(target, requestingBeanName)); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } } } public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { private class AutowiredFieldElement extends InjectionMetadata.InjectedElement { @Override protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { // 拿到這個欄位名 Field field = (Field) this.member; Object value; // 大多數情況下,這裡都是 false if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); // 轉換器,沒有手動註冊,預設都是 SimpleTypeConverter TypeConverter typeConverter = beanFactory.getTypeConverter(); try { // 把當前 bean 所依賴的這個 Bean 解析出來(從 Spring 容器裡面拿,或者別的地方獲取) value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } synchronized (this) { if (!this.cached) { // 如果已經拿到了這個 Bean 例項 if (value != null || this.required) { this.cachedFieldValue = desc; // 把該 Bean 的依賴關係再註冊一次 registerDependentBeans(beanName, autowiredBeanNames); // 因為是按照型別注入,所以肯定只能有一個,否則上面解析就已經報錯了 if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); // 這裡是來處理放置快取的欄位值 if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType()); } } } else { this.cachedFieldValue = null; } this.cached = true; } } } // 給該物件的該欄位賦值。注意這裡 makeAccessible 設定為 true 了,所以即使你的欄位是 private 的也可以 if (value != null) { ReflectionUtils.makeAccessible(field); field.set(bean, value); } } private class AutowiredMethodElement extends InjectionMetadata.InjectedElement { @Override protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
initializeBean 做 Bean 初始化操作
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { // 先執行所有的 AwareMethods if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 執行所有的 BeanPostProcessor#postProcessBeforeInitialization,初始化之前的處理器方法 // 規則:只要誰反回了 null,後面的就都不要執行了 // 這裡面實現 postProcessBeforeInitialization 的處理器就很多了,有很多對 Aware 進行了擴充套件的 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 這裡就開始執行 afterPropertiesSet(實現了 InitializingBean 介面)方法和 initMethod // 備註:這裡 initMethod 方法的名稱不能是 afterPropertiesSet,並且這個類不是 InitializingBean 型別才會呼叫,需要特別注意。 // (然後該方法只有方法名,所以肯定是反射呼叫,效率稍微低那麼一丟丟) // 由此可以見,實現這個介面的初始化方法,是在標註形如 @PostConstruct 之後執行的 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()) { // 整個 Bean 都初始化完成了,就執行後置處理器的這個方法 // 如果誰反回了 null,後面的處理器都不會再執行了 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } // 相關 Aware 介面為:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware // 這些都是 spring 將資料暴露出去的一種方式,我們直接實現這個介面就能拿到了 private void invokeAwareMethods(String beanName, 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); } } }
initializeBean 中 applyBeanPostProcessorsBeforeInitialization 方法呼叫的一些BeanPostProcessor
class ApplicationContextAwareProcessor implements BeanPostProcessor { @Override @Nullable public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { return bean; } AccessControlContext acc = null; if (System.getSecurityManager() != null) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null; }, acc); } else { invokeAwareInterfaces(bean); } return bean; } private void invokeAwareInterfaces(Object bean) { 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); } } // 對 bean 進行資料校驗 public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!this.afterInitialization) { doValidate(bean); } return bean; } class BootstrapContextAwareProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (this.bootstrapContext != null && bean instanceof BootstrapContextAware) { ((BootstrapContextAware) bean).setBootstrapContext(this.bootstrapContext); } return bean; } public class ServletContextAwareProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (getServletContext() != null && bean instanceof ServletContextAware) { ((ServletContextAware) bean).setServletContext(getServletContext()); } if (getServletConfig() != null && bean instanceof ServletConfigAware) { ((ServletConfigAware) bean).setServletConfig(getServletConfig()); } return bean; } public class LoadTimeWeaverAwareProcessor implements BeanPostProcessor, BeanFactoryAware { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof LoadTimeWeaverAware) { LoadTimeWeaver ltw = this.loadTimeWeaver; if (ltw == null) { Assert.state(this.beanFactory != null, "BeanFactory required if no LoadTimeWeaver explicitly specified"); ltw = this.beanFactory.getBean(ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME, LoadTimeWeaver.class); } ((LoadTimeWeaverAware) bean).setLoadTimeWeaver(ltw); } return bean; } // 處理宣告週期註解方法的處理器。有了它,就允許用 @PostConstruct 和 @PreDestroy 註解去代替 InitializingBean 和 DisposableBean 介面 public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeInitMethods(bean, beanName); } catch (InvocationTargetException ex) { throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Failed to invoke init method", ex); } return bean; }
initializeBean 中 applyBeanPostProcessorsAfterInitialization 方法呼叫的一些BeanPostProcessor
// 把所有的 ApplicationListener 的 Bean,都加入到 addApplicationListener,放到廣播器裡面 class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) { if (bean instanceof ApplicationListener) { // potentially not detected as a listener by getBeanNamesForType retrieval Boolean flag = this.singletonNames.get(beanName); if (Boolean.TRUE.equals(flag)) { // singleton bean (top-level or inner): register on the fly this.applicationContext.addApplicationListener((ApplicationListener<?>) bean); } else if (Boolean.FALSE.equals(flag)) { if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) { // inner bean with other scope - can't reliably process events logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " + "but is not reachable for event multicasting by its containing ApplicationContext " + "because it does not have singleton scope. Only top-level listener beans are allowed " + "to be of non-singleton scope."); } this.singletonNames.remove(beanName); } } return bean; } // 校驗 public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (this.afterInitialization) { doValidate(bean); } return bean; } // 解析方法中標註有 @Scheduled 註解的,然後加入當作一個任務進行執行 public class ScheduledAnnotationBeanPostProcessor implements ScheduledTaskHolder, MergedBeanDefinitionPostProcessor, DestructionAwareBeanPostProcessor, Ordered, EmbeddedValueResolverAware, BeanNameAware, BeanFactoryAware, ApplicationContextAware, SmartInitializingSingleton, ApplicationListener<ContextRefreshedEvent>, DisposableBean { @Override public Object postProcessAfterInitialization(Object bean, String beanName) { if (bean instanceof AopInfrastructureBean || bean instanceof TaskScheduler || bean instanceof ScheduledExecutorService) { // Ignore AOP infrastructure such as scoped proxies. return bean; } Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean); if (!this.nonAnnotatedClasses.contains(targetClass) && AnnotationUtils.isCandidateClass(targetClass, Arrays.asList(Scheduled.class, Schedules.class))) { Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> { Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(method, Scheduled.class, Schedules.class); return (!scheduledMethods.isEmpty() ? scheduledMethods : null); }); if (annotatedMethods.isEmpty()) { this.nonAnnotatedClasses.add(targetClass); if (logger.isTraceEnabled()) { logger.trace("No @Scheduled annotations found on bean class: " + targetClass); } } else { // Non-empty set of methods annotatedMethods.forEach((method, scheduledMethods) -> scheduledMethods.forEach(scheduled -> processScheduled(scheduled, method, bean))); if (logger.isTraceEnabled()) { logger.trace(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName + "': " + annotatedMethods); } } } return bean; } // 當 Servlet 是以 Bean 的形式注入容器的時候,Bean 初始化完成後,會自動呼叫它的 init 方法 // 如果 config 為 null,那麼它傳入可能為代理的 DelegatingServletConfig public class SimpleServletPostProcessor implements DestructionAwareBeanPostProcessor, ServletContextAware, ServletConfigAware { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Servlet) { ServletConfig config = this.servletConfig; if (config == null || !this.useSharedServletConfig) { config = new DelegatingServletConfig(beanName, this.servletContext); } try { ((Servlet) bean).init(config); } catch (ServletException ex) { throw new BeanInitializationException("Servlet.init threw exception", ex); } } return bean; }
整個 initializeBean流程
- 呼叫各類 Aware 介面
- 執行 applyBeanPostProcessorsBeforeInitialization 初始化前的處置操作
- 呼叫 InitializingBean 介面初始化 (如果配置了 method-init,則呼叫其方法初始化 )
- 呼叫 applyBeanPostProcessorsAfterInitialization 初始化之後的處置操作
執行 finishBeanFactoryInitialization() 後的容器
Note:Spring 中方法呼叫層級,對於某個功能中涉及到許多輔助類的邏輯(快取、前後置處理等)時,可以把這些輔助類邏輯放到功能方法中,把真正的功能邏輯抽取到 doXxx() 方法裡。
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // 省略其它無關程式碼... object = doGetObjectFromFactoryBean(factory, beanName); }
https://blog.csdn.net/f641385712/article/details/88410362