本篇文章主要分析 Spring IoC 的 createBean()
方法的流程,以及 bean
的生命週期。java
下面是一個大體的流程圖:git
@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. // 將String類型的class字符串,轉換爲Class對象,例如在XML中配置的class屬性 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { // 進行定義的方法覆蓋 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. // 若是bean的實例化前回調方法返回非null,直接返回實例,跳事後面步驟 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 { // 真正去建立bean的方法 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } // 返回bean的實例 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); } }
上面方法若是 resolveBeforeInstantiation()
返回非 null
,則會跳事後面步驟,直接返回實例。這也是一個擴展點,給 BeanPostProcessor
一個機會來返回代理來替代真正的實例。github
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; // 判斷bean在實例化以前是否已經解析過 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. // 若是bean是合成的 && 有實現 InstantiationAwareBeanPostProcessor 接口 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // 解析bean的類型 Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { // 執行bean的實例化前回調 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); // 若是實例化前生命週期回調方法返回的不是null if (bean != null) { // 執行bean的實例化後回調,由於只能在此處調用了 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } // 若是bean不爲空,則將beforeInstantiationResolved賦值爲true,表明在實例化以前已經解析 mbd.beforeInstantiationResolved = (bean != null); } return bean; }
上面方法主要是判斷 bean
以前沒有解析過而且有註冊 InstantiationAwareBeanPostProcessor
接口,而後這裏會調用 bean
實例化前的回調方法,若是返回非空,會調用 bean
實例化後的回調方法;由於返回非空,後續正常的流程都不會走了,因此只能在此處調用。spring
下面是 InstantiationAwareBeanPostProcessor
接口,以下:數組
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { /** * Bean 實例化前調用,返回非 {@code null} IoC 容器不會對 Bean 進行實例化 而且後續的生命週期回調方法不 * 調用,返回 {@code null} 則進行 IoC 容器對 Bean 的實例化 */ @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } /** * Bean 實例化以後,屬性填充以前調用,返回 {@code true} 則進行默認的屬性填充步驟,返回 {@code false} * 會跳過屬性填充階段,一樣也會跳過初始化階段的生命週期方法的回調 */ default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } /** * Bean 實例化後屬性賦值前調用,PropertyValues 是已經封裝好的設置的屬性值,返回 {@code null} 繼續 * 使用現有屬性,不然會替換 PropertyValues */ @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } /** * 跟上面方法同樣,不過是之前版本使用的 */ @Deprecated @Nullable default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }
上面接口提供了三個擴展點,以下:緩存
bean
實例化前bean
實例化後bean
屬性賦值前這也是 bean
實例化的生命週期回調方法。app
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 若是bean的做用域是singleton,則須要移除未完成的FactoryBean實例的緩存 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 經過構造函數反射建立bean的實例,可是屬性並未賦值 instanceWrapper = createBeanInstance(beanName, mbd, args); } // 獲取bean的實例 final Object bean = instanceWrapper.getWrappedInstance(); // 獲取bean的類型 Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // BeanDefinition 合併後的回調,見下文詳解 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正在建立中 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); // 若是容許bean提早曝光 if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 將beanName和ObjectFactory造成的key-value對放入singletonFactories緩存中 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { // 給 bean 的屬性賦值 populateBean(beanName, mbd, instanceWrapper); // 初始化 bean 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); } } // 若是容許單例bean提早暴露 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); // 只有在檢測到循環依賴的狀況下才不爲空 if (earlySingletonReference != null) { // 若是exposedObject沒有在初始化方法中被改變,也就是沒有被加強 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 " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { // 用於註冊銷燬bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } // 返回bean實例 return exposedObject; }
/** * @param args getBean() 中的 args 參數 * @return bean 實例包裝後的 BeanWrapper */ 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); // 判斷beanClass是不是public修飾的類,而且是否容許訪問非公共構造函數和方法,不是拋出異常 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()); } // Spring 5新添加的,若是存在Supplier回調,則使用給定的回調方法初始化策略。可使RootBeanDefinition#setInstanceSupplier()設置 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } // 若是設置工廠方法則使用給定的方法建立bean實例,這裏分爲靜態工廠和實例化工廠 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... // resolved: 構造函數或工廠方法是否已經解析過 boolean resolved = false; // autowireNecessary: 是否須要自動注入 (便是否須要解析構造函數) boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { // 若是resolvedConstructorOrFactoryMethod不爲空,表明構造函數或工廠方法已經解析過 if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; // 根據constructorArgumentsResolved判斷是否須要自動注入 autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { // 若是構造函數或工廠方法已經解析過而且須要自動注入,則執行構造器自動注入,見下文詳解 return autowireConstructor(beanName, mbd, null, null); } else { // 不然使用默認構造函數進行bean實例化,見下文詳解 return instantiateBean(beanName, mbd); } } // Candidate constructors for autowiring? // 應用後置處理器,SmartInstantiationAwareBeanPostProcessor 拿到 bean 的候選構造函數 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // 候選構造函數不爲空 || 構造函數依賴注入 || 定義了構造函數的參數值 || args不爲空,則執行構造器自動注入 if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // Preferred constructors for default construction? // 若是有首選的構造函數,使用該構造函數去建立bean實例 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } // No special handling: simply use no-arg constructor. // 沒有特殊處理,使用默認無參構造器實例化bean return instantiateBean(beanName, mbd); }
上面代碼主要判斷是使用構函數自動注入,仍是使用默認構造函數構造。總結起來如下幾種狀況會使用構造函數自動注入:less
SmartInstantiationAwareBeanPostProcessor
接口中的 determineCandidateConstructors()
BeanDefinition
定義了構造函數參數,如 XML 中的 <constructor-arg index="0" value="1"/>
getBean()
時顯示指定了 args
參數protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, parent), getAccessControlContext()); } else { // 使用指定的策略去實力化bean beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } // 將實例化後的bean封裝成BeanWrapper後返回 BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } } // SimpleInstantiationStrategy.java public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. // 若是有須要覆蓋或者動態替換的方法則固然須要使用CGLIB進行動態代理,由於能夠在建立代理的同時將方法織入類中 // 可是若是沒有須要動態改變的方法,爲了方便直接用反射就能夠了 if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { // 獲取緩存的構造方法或工廠方法 constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; // 緩存爲空 if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); // 若是clazz是接口,拋出異常 if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged( (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor); } else { // 獲取默認的無參構造函數 constructorToUse = clazz.getDeclaredConstructor(); } // 設置緩存 bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } // 這裏就是用指定的無參構造器去實例化該bean,不作具體分析了 return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. // 用CGLIB生成子類動態織入重寫的方法 return instantiateWithMethodInjection(bd, beanName, owner); } }
上面代碼比較簡單,無非就是使用默認的無參構造器去實例化 bean
,並封裝成 BeanWrapper
返回。ide
protected BeanWrapper autowireConstructor( String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) { // 尋找適合的構造器,進行實例化 return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs); } public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw); // 最終實例化的構造函數 Constructor<?> constructorToUse = null; // 最終用於實例化的參數Holder ArgumentsHolder argsHolderToUse = null; // 最終用於實例化的構造函數參數 Object[] argsToUse = null; // 若是explicitArgs不爲空,則使用explicitArgs當作構造器函數參數 if (explicitArgs != null) { argsToUse = explicitArgs; } else { Object[] argsToResolve = null; synchronized (mbd.constructorArgumentLock) { // 獲取已經緩存的構造函數或工廠方法 constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod; if (constructorToUse != null && mbd.constructorArgumentsResolved) { // Found a cached constructor... // 獲取已經緩存的構造函數參數 argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null) { // 若是已經緩存了構造函數或工廠方法,那麼resolvedConstructorArguments和preparedConstructorArguments一定有一個緩存了構造函數參數 argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null) { // 若是argsToResolve不爲空,則對構造函數參數進行解析,也就是會進行類型轉換之類的操做 // 例如 A(int,int),把配置中的 ("1","1") 轉換爲 (1,1) argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true); } } // 若是沒有緩存構造函數或者其參數 if (constructorToUse == null || argsToUse == null) { // Take specified constructors, if any. Constructor<?>[] candidates = chosenCtors; if (candidates == null) { Class<?> beanClass = mbd.getBeanClass(); try { // 若是容許訪問非public的構造函數和方法(該值默認爲 true),就獲取全部構造函數,不然只獲取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); } } // 若是隻有一個構造函數 && getBean()沒有顯示指定args && 沒有定義構造函數的參數值 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; } // 經過無參構造函數建立bean的實例,而後直接返回 bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS)); return bw; } } // Need to resolve the constructor. // 若是候選構造函數不爲空 || 構造函數自動注入模式 boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null; int minNrOfArgs; // getBean()顯示指定了參數,獲取參數長度 if (explicitArgs != null) { minNrOfArgs = explicitArgs.length; } else { // 獲取定義的構造函數參數 ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); // 解析構造函數參數並賦值到resolvedValues,返回參數個數。見下文詳解 minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } // 這裏對構造函數進行排序,規則是首先是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(); // 若是已經找到知足的構造函數 && 目標構造函數參數個數大於當前遍歷的構造函數參數個數則終止 // 由於構造函數已是排過序的,後面不會再有更適合的了 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 { // 評估參數名稱,就是判斷構造函數上是否標註了@ConstructorProperties註解,若是標註了,直接取其中定義的參數名稱 String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount); // 沒有標註@ConstructorProperties註解,使用參數名稱解析器,獲取參數名稱 if (paramNames == null) { ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); if (pnd != null) { paramNames = pnd.getParameterNames(candidate); } } // 建立一個參數數組以調用構造函數或工廠方法,見下文詳解 // 主要是經過參數類型和參數名解析構造函數或工廠方法所需的參數(若是參數是其餘bean,則會解析依賴的bean) 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; } } // resolvedValues爲空, explicitArgs不爲空,即顯示指定了getBean()的args參數 else { // Explicit arguments given -> arguments length must match exactly. // 若是當前構造函數參數個數不等的explicitArgs的長度,直接跳過該構造函數 if (parameterCount != explicitArgs.length) { continue; } // 把explicitArgs封裝進ArgumentsHolder argsHolder = new ArgumentsHolder(explicitArgs); } // 根據mbd的解析構造函數模式(true: 寬鬆模式,false:嚴格模式) // 將argsHolder的參數和paramTypes進行比較,計算paramTypes的類型差別權重值 int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); // Choose this constructor if it represents the closest match. // 差別值越小表明構造函數越匹配,則選擇此構造函數 if (typeDiffWeight < minTypeDiffWeight) { constructorToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; // 若是出現權重值更小的候選者,則將ambiguousConstructors清空,容許以前存在權重值相同的候選者 ambiguousConstructors = null; } // 兩個候選者權重值相同,而且是當前遍歷過權重值最小的 else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) { // 將兩個候選者添加到ambiguousConstructors 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); } // getBean()方法沒有指定args參數 && 構造函數參數不爲空 if (explicitArgs == null && argsHolderToUse != null) { // 緩存解析事後的構造函數和參數 argsHolderToUse.storeCache(mbd, constructorToUse); } } Assert.state(argsToUse != null, "Unresolved constructor arguments"); // 利用反射建立bean實例 bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse)); return bw; }
上面代碼的功能主要以下:函數
explicitArgs
參數不爲空,那就能夠直接肯定參數。由於 explicitArgs
參數是在調用 getBean()
時手動指定的,這個主要用於靜態工廠方法的調用。BeanDefinition
中讀取,咱們所定義的 bean
都會生成一個 BeanDefinition
,其中記錄了定義了構造函數參數經過 getConstructorArgumentValues()
獲取。public
構造函數且參數個數從多到少,而後是非public
構造函數且參數個數有多到少。這樣能夠迅速判斷排在後面的構造函數參數個數是否符合條件。bean
。private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) { // 獲取自定義類型轉換器 TypeConverter customConverter = this.beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); // 若是沒有自定義的轉換器就用bw BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); // minNrOfArgs初始化爲indexedArgumentValues+genericArgumentValues的個數總和 int minNrOfArgs = cargs.getArgumentCount(); // 遍歷IndexArgumentValues,這裏的IndexArgumentValues就帶下標的,如:<constructor-arg index="0" value="1"/> for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) { int index = entry.getKey(); if (index < 0) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid constructor argument index: " + index); } // 若是index大於minNrOfArgs,修改minNrOfArgs值 if (index > minNrOfArgs) { // 由於index是構造函數下標值,因此總數這邊要加1 minNrOfArgs = index + 1; } ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue(); // 若是參數類型已經轉換過,直接添加進resolvedValues if (valueHolder.isConverted()) { resolvedValues.addIndexedArgumentValue(index, valueHolder); } // 參數類型沒有轉換過,進行轉換 else { Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); // 使用轉換過的參數值構建ValueHolder ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); // 添加進resolvedValues resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder); } } // 遍歷GenericArgumentValues並進行類型轉換和上面同樣,這裏的GenericArgumentValues就是沒有指定下標的,如:<constructor-arg value="1"/> for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) { if (valueHolder.isConverted()) { resolvedValues.addGenericArgumentValue(valueHolder); } else { Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue()); ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder( resolvedValue, valueHolder.getType(), valueHolder.getName()); resolvedValueHolder.setSource(valueHolder); resolvedValues.addGenericArgumentValue(resolvedValueHolder); } } // 返回參數個數 return minNrOfArgs; }
上面代碼主要將 indexedArgumentValues
和 genericArgumentValues
的值調用 resolveValueIfNecessary()
進行解析;resolveValueIfNecessary()
主要解析參數的類型,好比 ref
屬性引用的 beanName
會經過 getBean()
返回實例。
private ArgumentsHolder createArgumentArray( String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException { // 獲取類型轉換器 TypeConverter customConverter = this.beanFactory.getCustomTypeConverter(); TypeConverter converter = (customConverter != null ? customConverter : bw); // 構建ArgumentsHolder ArgumentsHolder args = new ArgumentsHolder(paramTypes.length); Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length); Set<String> autowiredBeanNames = new LinkedHashSet<>(4); // 遍歷參數類型數組 for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) { // 獲取參數類型和名稱 Class<?> paramType = paramTypes[paramIndex]; String paramName = (paramNames != null ? paramNames[paramIndex] : ""); // Try to find matching constructor argument value, either indexed or generic. ConstructorArgumentValues.ValueHolder valueHolder = null; if (resolvedValues != null) { // 根據參數的下標、類型、名稱查詢是否有匹配的 valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders); // If we couldn't find a direct match and are not supposed to autowire, // let's try the next generic, untyped argument value as fallback: // it could match after type conversion (for example, String -> int). // 沒有匹配的 && 不是自動裝配。嘗試下一個通用的無類型參數值做爲降級方法,它能夠在類型轉換後匹配 (例如,String -> int) if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) { valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders); } } // 找到了匹配的valueHolder if (valueHolder != null) { // We found a potential match - let's give it a try. // Do not consider the same value definition multiple times! // 添加進usedValueHolders usedValueHolders.add(valueHolder); Object originalValue = valueHolder.getValue(); Object convertedValue; // 類型已經轉換過 if (valueHolder.isConverted()) { // 獲取已經轉換過的值,做爲args在paramIndex的預備參數 convertedValue = valueHolder.getConvertedValue(); args.preparedArguments[paramIndex] = convertedValue; } // 類型沒有轉換過 else { // 將構造方法和參數下標封裝成MethodParameter(MethodParameter是封裝方法和參數索引的工具類) MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex); try { // 將原始值轉換爲paramType類型的值,沒法轉換時拋出異常 convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam); } catch (TypeMismatchException ex) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(valueHolder.getValue()) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage()); } Object sourceHolder = valueHolder.getSource(); if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) { Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue(); // 標記args須要解析 args.resolveNecessary = true; // 將sourceValue做爲args在paramIndex位置的預備參數 args.preparedArguments[paramIndex] = sourceValue; } } // 將convertedValue做爲args在paramIndex位置的參數 args.arguments[paramIndex] = convertedValue; // 將originalValue做爲args在paramIndex位置的原始參數 args.rawArguments[paramIndex] = originalValue; } // 沒有找到匹配的valueHolder else { // 將構造方法和參數下標封裝成MethodParameter MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex); // No explicit match found: we're either supposed to autowire or // have to fail creating an argument array for the given constructor. // 找不到明確的匹配,而且不是自動注入,拋出異常 if (!autowiring) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Ambiguous argument values for parameter of type [" + paramType.getName() + "] - did you specify the correct bean references as arguments?"); } try { // 若是是自動注入,用resolveAutowiredArgument()解析參數,見下文詳解 // 構造函數自動注入中的參數bean就是在這邊處理 Object autowiredArgument = resolveAutowiredArgument( methodParam, beanName, autowiredBeanNames, converter, fallback); // 將經過自動裝配解析出來的參數賦值給args args.rawArguments[paramIndex] = autowiredArgument; args.arguments[paramIndex] = autowiredArgument; args.preparedArguments[paramIndex] = autowiredArgumentMarker; args.resolveNecessary = true; } catch (BeansException ex) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex); } } } // 若是依賴了其餘的bean,則註冊依賴關係(這邊的autowiredBeanNames,就是全部依賴的beanName) for (String autowiredBeanName : autowiredBeanNames) { this.beanFactory.registerDependentBean(autowiredBeanName, beanName); if (logger.isDebugEnabled()) { logger.debug("Autowiring by type from bean name '" + beanName + "' via " + (executable instanceof Constructor ? "constructor" : "factory method") + " to bean named '" + autowiredBeanName + "'"); } } // 返回解析後的參數值 return args; }
上面代碼判斷構造函數若是有匹配的參數會轉換成對應類型,若是沒有匹配的參數,多半是構造函數自動注入,經過 resolveAutowiredArgument()
去查找 bean
並返回實例。
protected Object resolveAutowiredArgument(MethodParameter param, String beanName, @Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) { // 獲取參數的類型 Class<?> paramType = param.getParameterType(); // 若是參數類型是InjectionPoint if (InjectionPoint.class.isAssignableFrom(paramType)) { // 拿到當前的InjectionPoint(存儲了當前正在解析依賴的方法參數信息,DependencyDescriptor) InjectionPoint injectionPoint = currentInjectionPoint.get(); if (injectionPoint == null) { // 當前injectionPoint爲空,則拋出異常:目前沒有可用的InjectionPoint throw new IllegalStateException("No current InjectionPoint available for " + param); } // 當前injectionPoint不爲空,直接返回 return injectionPoint; } try { // 解析指定依賴,DependencyDescriptor:將MethodParameter的方法參數索引信息封裝成DependencyDescriptor,見下文詳解 return this.beanFactory.resolveDependency( new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter); } catch (NoUniqueBeanDefinitionException ex) { throw ex; } catch (NoSuchBeanDefinitionException ex) { if (fallback) { // Single constructor or factory method -> let's return an empty array/collection // for e.g. a vararg or a non-null List/Set/Map parameter. if (paramType.isArray()) { return Array.newInstance(paramType.getComponentType(), 0); } else if (CollectionFactory.isApproximableCollectionType(paramType)) { return CollectionFactory.createCollection(paramType, 0); } else if (CollectionFactory.isApproximableMapType(paramType)) { return CollectionFactory.createMap(paramType, 0); } } throw ex; } }
上面代碼咱們通常只須要重點關注 this.beanFactory.resolveDependency()
這個方法,這個就是解決依賴注入的祕密所在。
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); // Optional類型的處理,說明Spring也能夠注入Optional類型的參數 if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } // ObjectFactory或ObjectProvider類型的處理 else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } // javax.inject.Provider類型的處理 else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); } else { // 獲取延遲解析代理 Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { // 解析依賴,返回的result爲最終須要注入的bean實例,見下文詳解 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } return result; } }
上面代碼主要判斷若是須要注入的 bean
的類型是 Optional
、ObjectFactory
、ObjectProvider
、Provider
會作特殊的處理,通常狀況下注入的 bean
會走最後的 doResolveDependency()
。 還有一個比較重要的參數 DependencyDescriptor
,這個類就是依賴描述符,存儲了須要注入 bean
的類型、構造器參數的下標(構造器注入該值不爲空)、是否必需、字段名稱(字段注入該值不爲空)、方法名稱(setter
方法注入該值不爲空)等。
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { // 獲取須要注入bean的快捷方式,不爲空直接返回 Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } // 獲取須要注入bean的類型 Class<?> type = descriptor.getDependencyType(); // 用於支持Spring中新增的註解@Value(肯定給定的依賴項是否聲明@Value註解,若是有則拿到值) Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); try { return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); } catch (UnsupportedOperationException ex) { // A custom TypeConverter which does not support TypeDescriptor resolution... return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) :converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } } // 解析MultipleBean,例如 Array,Collection,Map Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 根據類型找到匹配的bean,matchingBeans(key: beanName value: 若是bean已經緩存了實例(例如單例bean會緩存其實例), // 就是bean的實例,不然就是對應的class對象) Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { // 沒有找到匹配的bean,判斷是否是必需的,不是直接返回null,不然拋出異常 if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; // 若是有多個匹配的候選者 if (matchingBeans.size() > 1) { // 判斷最佳的候選者,也就是尋找最匹配的beanName autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans); } else { // In case of an optional Collection/Map, silently ignore a non-unique case: // possibly it was meant to be an empty collection of multiple regular beans // (before 4.3 in particular when we didn't even look for collection beans). return null; } } // 拿到autowiredBeanName對應的value(bean實例或bean實例類型) instanceCandidate = matchingBeans.get(autowiredBeanName); } else { // We have exactly one match. // 只找到一個符合的bean Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } if (autowiredBeanNames != null) { // 將依賴的beanName添加到autowiredBeanNames中 autowiredBeanNames.add(autowiredBeanName); } // 若是須要注入的bean沒有緩存實例,那麼instanceCandidate是一個Class對象,再根據getBean()去獲取對應的實例 if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); } Object result = instanceCandidate; if (result instanceof NullBean) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null; } if (!ClassUtils.isAssignableValue(type, result)) { throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); } // 返回最終須要注入的bean實例 return result; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
上面代碼纔是真正去獲取須要注入的 bean
,大概分爲如下幾個步驟:
查看是否有快捷方式獲取注入 bean
是否爲空,不爲空直接返回。這裏的快捷方式是經過繼承 DependencyDescriptor
並重寫 resolveShortcut()
來實現。
若是參數使用 @Value
註解修飾了,若是獲取到值直接返回。
解析 MultipleBean
,這裏的 MultipleBean
通常是 Array
、Collection
、Map
這種,不爲空直接返回。
根據類型找到全部匹配的 bean
,matchingBeans
中 key
爲 beanName
,value
的值有兩種狀況,若是bean已經緩存了實例(例如單例bean會緩存其實例),就是bean的實例,不然就是對應的class對象)。
matchingBeans
爲空,判斷須要注入的 bean
是不是必須的,若是是拋出異常,不然返回 null
。
matchingBeans
長度大於1,表明有多個候選者;選擇最佳的候選者,規則是:
primary
屬性爲 true
的。PriorityOrdered
接口或者標註 @Priority
註解的。只有一個候選者,直接使用。
若是須要注入的 bean
沒有緩存實例,那麼 instanceCandidate
是一個 Class
對象,再根據 getBean()
去獲取對應的實例。
最終返回須要注入的 bean
實例。
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); } } }
上面代碼很簡單,無非就是拿到全部註冊的 BeanPostProcessor
,而後遍歷判斷是不是 MeragedBeanDefinitionPostProcessor
類型,是的話進行 BeanDefinition
合併後的方法回調,在這個回調方法內你能夠對指定 bean
的 BeanDefinition
作一些修改。
下面咱們簡單看一下 MergedBeanDefinitionPostProcessor
接口中的方法:
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor { /** * 對指定bean的BeanDefinition合併後的處理方法回調 */ void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName); /** * 通知已從新設置指定beanName的BeanDefinition,若是實現該方法應該清除受影響的bean的全部元數據 * @since 5.1 */ default void resetBeanDefinition(String beanName) { } }
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); // 加鎖 synchronized (this.singletonObjects) { // 若是單例bean緩存中不包含當前beanName if (!this.singletonObjects.containsKey(beanName)) { // 將建立實例的ObjectFactory加入到緩存中 this.singletonFactories.put(beanName, singletonFactory); // 將bean從早起單例bean緩存中移除 this.earlySingletonObjects.remove(beanName); // 將beanName加入到已經註冊過的單例bean緩存中 this.registeredSingletons.add(beanName); } } }
上面代碼將 ObjectFactory
加入 singletonFactories
緩存中,如下是 singletonFactories
的聲明:
/** Cache of singleton factories: bean name to ObjectFactory. */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
下面以一個簡單的AB循環依賴爲例,類A中含有屬性類B,而類B中又會含有屬性類A。那麼初始化 beanA 的過程以下圖所示:
Spring 解決循環依賴的方法就在 addSingletonFactory()
和 getBean()
方法中。首先建立 beanA
時,將實例化好的 beanA
封裝成 ObjectFactory
放入 singletonFactories
緩存中,接着進行屬性填充;由於依賴 beanB
因此先去實例化 beanB
,接着 beanB
屬性填充,發現須要 beanA
就調用 getBean()
去獲取 beanA
實例。上篇文章講過 getBean()
會首先判斷緩存中是否有已經建立好的 bean
或者是 beanFactory
,以下代碼所示:
protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 檢查單例傳中是否存在 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { // 若是爲空,而且當前bean正在建立中,鎖定全局變量進行處理 synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { // 當某些方法須要提早初始化時則會調用addSingletonFactory方法將對應的 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { // 調用預先設定的getObject(),此時就會返回未填充屬性的beanA singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
由於 beanA
與 beanB
中的 beanA
所表示的屬性地址是同樣的,因此在 beanA
中建立好的屬性填充天然能夠經過 beanB
中的 beanA
獲取,這樣就解決了循環依賴的問題。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }
上面代碼很簡單,就是判斷是否有註冊 InstantiationAwareBeanPostProcessor
的實現,若是有遍歷找到類型是 SmartInstantiationAwareBeanPostProcessor
調用 getEarlyBeanReference()
返回 bean
的實例。
這裏又是一個 Spring 的擴展點,其中咱們熟知的 AOP 就是在這裏將 advice
動態織入 bean
中,若沒有則直接返回 bean
,不作任何處理。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { 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 // 例如:能夠用來支持屬性注入的類型 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { // 這裏會調用bean實例化後的生命週期回調,返回false會跳過下面的屬性賦值階段 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // 獲取PropertyValues PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); 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; } // 是否有註冊InstantiationAwareBeanPostProcessors的實現類 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } // 遍歷並找到InstantiationAwareBeanPostProcessor的實現類,調用處理屬性值的後置處理方法 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); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); // 若是屬性值的後置處理方法返回null,直接返回,不會進行底下的屬性值應用階段 if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { // 屬性填充,見下文詳解 applyPropertyValues(beanName, mbd, bw, pvs); } }
上面代碼首先會調用 bean
的實例化後生命週期回調方法,若是返回 false
會跳過下面的屬性賦值階段。下面咱們簡單看一下 InstantiationAwareBeanPostProcessors
的接口定義:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { /** * Bean 實例化前調用,返回非 {@code null} IoC 容器不會對 Bean 進行實例化 而且後續的生命週期回調方 * 法不會調用,返回 {@code null} 則進行 IoC 容器對 Bean 的實例化 * 該方法上篇文章分析過 */ @Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; } /** * Bean 實例化以後,屬性填充以前調用,返回 {@code true} 則進行默認的屬性填充步驟,返回 {@code * false} 會跳過屬性填充階段。 */ default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; } /** * Bean 實例化後屬性賦值前調用,PropertyValues 是已經封裝好的設置的屬性值,返回 {@code null} 繼續 * 使用現有屬性,不然會替換 PropertyValues。 * @since 5.1版本新加的和底下的方法同樣 */ @Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } /** * 跟上面方法同樣的功能,只不過是5.1之前版本所使用的 * 返回 {@code null} 會跳過屬性填充階段 */ @Deprecated @Nullable default PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; } }
接着判斷是不是按 名稱 或者 類型 自動注入屬性並填入 newPvs
中,接着調用 bean
屬性填充前的生命週期回調。屬性填充前生命週期回調方法有兩個 postProcessProperties()
和 postProcessPropertyValues()
,第一個是 Spring 5.1 新加的,後面的是老的,已經被標記爲過期;首先會調用 postProcessProperties()
若是返回空調用 postProcessPropertyValues()
,不然直接使用返回的 PropertyValues
;postProcessPropertyValues()
若是返回空會直接跳過屬性填充階段,不爲空直接使用返回的 PropertyValues
。
protected void autowireByName( String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { // 尋找bw中須要依賴注入的屬性名稱 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); // 遍歷須要注入的bean for (String propertyName : propertyNames) { if (containsBean(propertyName)) { Object bean = getBean(propertyName); // 將須要注入bean的實例加入到pvs pvs.add(propertyName, bean); // 註冊依賴關係,上篇文章有分析過 registerDependentBean(propertyName, beanName); if (logger.isTraceEnabled()) { logger.trace("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'"); } } else { // 當前須要注入的bean,拋出異常 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) { TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set<String> autowiredBeanNames = new LinkedHashSet<>(4); // 尋找bw中須要依賴注入的屬性名稱 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()) { // 獲取屬性的可寫方法,通常是set方法 MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); // Do not allow eager init for type matching in case of a prioritized post-processor. boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered); DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager); // 這個方法上面分析過,這裏再也不贅述,最後返回符合條件須要注入的bean實例 Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowiredArgument != null) { // 須要注入的bean實例不爲空,加入到pvc 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); } } }
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { // 屬性爲空,直接返回 if (pvs.isEmpty()) { return; } if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) { ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } MutablePropertyValues mpvs = null; List<PropertyValue> original; if (pvs instanceof MutablePropertyValues) { mpvs = (MutablePropertyValues) pvs; // 快捷方式,若是屬性已經轉換過,直接填充進BeanWrapper if (mpvs.isConverted()) { // Shortcut: use the pre-converted values as-is. try { bw.setPropertyValues(mpvs); return; } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } } // 屬性沒有轉換過,獲取屬性列表 original = mpvs.getPropertyValueList(); } else { // 獲取屬性列表 original = Arrays.asList(pvs.getPropertyValues()); } TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } // 獲取對應的解析器 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); // Create a deep copy, resolving any references for values. // 建立深拷貝,解決引用的問題 List<PropertyValue> deepCopy = new ArrayList<>(original.size()); boolean resolveNecessary = false; // 遍歷屬性,將屬性轉換爲對應的類型 for (PropertyValue pv : original) { // 若是pv類型轉換過,直接添加進deepCopy if (pv.isConverted()) { deepCopy.add(pv); } else { // 進行轉換 // 拿到pv原始屬性名和屬性值 String propertyName = pv.getName(); Object originalValue = pv.getValue(); if (originalValue == AutowiredPropertyMarker.INSTANCE) { Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod(); if (writeMethod == null) { throw new IllegalArgumentException("Autowire marker for property without write method: " + pv); } originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true); } // 進行類型轉換 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); Object convertedValue = resolvedValue; boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName); if (convertible) { // 若是可轉換,則轉換指定目標屬性的給定值 convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter); } // Possibly store converted value in merged bean definition, // in order to avoid re-conversion for every created bean instance. // 在合併的BeanDefinition中存儲轉換後的值,以免爲每一個建立的bean實例從新轉換 if (resolvedValue == originalValue) { if (convertible) { pv.setConvertedValue(convertedValue); } deepCopy.add(pv); } else if (convertible && originalValue instanceof TypedStringValue && !((TypedStringValue) originalValue).isDynamic() && !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) { pv.setConvertedValue(convertedValue); deepCopy.add(pv); } else { resolveNecessary = true; deepCopy.add(new PropertyValue(pv, convertedValue)); } } } if (mpvs != null && !resolveNecessary) { mpvs.setConverted(); } // Set our (possibly massaged) deep copy. try { // 填充bean屬性值 bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Error setting property values", ex); } }
上面代碼主要就是進行屬性的類型轉換,最後填充 bean
的屬性值,這裏通常就是利用反射使用 set()
去給屬性賦值。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // BeanAware的接口回調,見下文詳解 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // BeanPostProcessor的postProcessBeforeInitialization()回調,也就是bean初始化前的回調 // 在 ApplicationContextAwareProcessor實現的postProcessBeforeInitialization方法中會執行 // ApplicationContext Aware的接口回調。 // InitDestoryAnnotationBeanPostProcessor的postProcessBeforeInitialization()中會執行 // 標註了@PostConstruct註解的方法。 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 調用bean的自定義初始化方法,如afterPropertiesSet,XML中的init屬性指定的方法等 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()) { // BeanPostProcessor的postProcessAfterInitialization()回調,也就是bean初始化後的回調 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { // BeanNameAware接口方法回調 if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } // BeanClassLoaderAware接口方法回調 if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } // BeanFactoryAware接口方法回調 if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
實現這些 Aware
接口的 bean
的被初始化以前,能夠取得一些相對應的資源,好比 beanName
、beanFactory
等。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 遍歷全部註冊的BeanPostProcessor實現類,調用postProcessBeforeInitialization方法 for (BeanPostProcessor processor : getBeanPostProcessors()) { // 在bean初始化方法執行前,調用postProcessBeforeInitialization方法 Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { // bean是否實現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>) () -> { ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 調用afterPropertiesSet方法 ((InitializingBean) bean).afterPropertiesSet(); } } // 調用自定義的init方法,例如XML中init-method屬性設置的方法 if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } }
綜合上面的代碼來看,bean
初始化階段流程主要以下:
@PostConstruct
註解修飾的方法,前提是註解驅動InitializingBean
接口的 afterPropertySet()
init-method
屬性設置的方法public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 遍歷全部註冊的BeanPostProcessor實現類,調用postProcessAfterInitialization方法 for (BeanPostProcessor processor : getBeanPostProcessors()) { // 在bean初始化方法執行後,調用postProcessBeforeInitialization方法 Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
下面咱們簡單看一下 BeanPostProcessor
接口,以下:
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
BeanPostProcessor
接口比較簡單,就提供了兩個接口回調,一個初始化前,一個初始化後。可是其它的 PostProcessor
大部門以此爲基礎,繼承自 BeanPostProcessor
。
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); // bean的做用域不是原型 && bean須要在關閉時銷燬 if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // 單例模式下注冊用於銷燬的bean到disposableBeans緩存,執行給定bean的全部銷燬工做: // DestructionAwareBeanPostProcessors,DisposableBean接口,自定義銷燬方法 // DisposableBeanAdapter:使用DisposableBeanAdapter來封裝用於銷燬的bean // 見下文詳解 registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... // bean是自定義做用域 Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } // 註冊一個回調,在銷燬時執行,執行時機本身去管理,Spring不會幫忙調用 scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition, List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) { Assert.notNull(bean, "Disposable bean must not be null"); this.bean = bean; this.beanName = beanName; // 判斷bean是否要調用DisposableBean的destroy方法 this.invokeDisposableBean = (this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy")); this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed(); this.acc = acc; // 獲取自定義的destroy方法名,賦值給destroyMethodName String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition); if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) && !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) { // 獲取自定義的destroy方法名賦值給destroyMethodName this.destroyMethodName = destroyMethodName; Method destroyMethod = determineDestroyMethod(destroyMethodName); // 若是斷定後的destroyMethod爲空,拋出異常 if (destroyMethod == null) { if (beanDefinition.isEnforceDestroyMethod()) { throw new BeanDefinitionValidationException("Could not find a destroy method named '" + destroyMethodName + "' on bean with name '" + beanName + "'"); } } // 若是斷定後的destroyMethod不爲空 else { // 獲取destroyMethod的方法參數 Class<?>[] paramTypes = destroyMethod.getParameterTypes(); // 參數長度大於1拋出異常,自定義的destroy方法最多隻容許有一個boolean參數 if (paramTypes.length > 1) { throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + beanName + "' has more than one parameter - not supported as destroy method"); } // 參數長度等於1 && 不是boolean類型,拋出異常 else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) { throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" + beanName + "' has a non-boolean parameter - not supported as destroy method"); } destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod); } this.destroyMethod = destroyMethod; } // 查找DestructionAwareBeanPostProcessors,並賦值給this.beanPostProcessors,見下文詳解 this.beanPostProcessors = filterPostProcessors(postProcessors, bean); }
private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) { List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null; // processors長度不爲空 if (!CollectionUtils.isEmpty(processors)) { // 遍歷processors for (BeanPostProcessor processor : processors) { // 若是processor的類型是DestructionAwareBeanPostProcessor if (processor instanceof DestructionAwareBeanPostProcessor) { DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor; // 若是bean實際須要經過此後置處理器進行銷燬,則添加到filteredPostProcessors if (dabpp.requiresDestruction(bean)) { filteredPostProcessors.add(dabpp); } } } } return filteredPostProcessors; }
上面的代碼主要就是判斷若是 BeanPostProcessor
是 DestructionAwareBeanPostProcessor
而且 requiresDestruction()
返回 true
表明須要經過後置處理器進行銷燬實例,將該 BeanPostProcessor
添加到 filteredPostProcessors
中。
下面咱們簡單看一下 DestructionAwareBeanPostProcessor
接口的定義:
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor { /** * bean 銷燬前階段生命週期回調方法 */ void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException; /** * bean 實例是否要由此後置處理器進行實例的銷燬 */ default boolean requiresDestruction(Object bean) { return true; } }
能夠看到其也是繼承於 BeanPostProcessor
,主要提供兩個方法一個是 bean
銷燬前的生命週期方法回調,另外一個是斷定 bean
實例是否要由此後置處理器進行實例的銷燬。
由於基本上 BeanFactory
就只會使用 DefaultListableBeanFactory
這一個最終實現,因此咱們這裏分析一下這裏的銷燬單例 bean
的方法。
public void destroySingletons() { // 調用父類的銷燬全部單例bean方法 super.destroySingletons(); updateManualSingletonNames(Set::clear, set -> !set.isEmpty()); // 清除全部bean類型的緩存 clearByTypeCache(); } // DefaultSingletonBeanRegistry.java public void destroySingletons() { if (logger.isTraceEnabled()) { logger.trace("Destroying singletons in " + this); } synchronized (this.singletonObjects) { this.singletonsCurrentlyInDestruction = true; } String[] disposableBeanNames; // 獲取全部須要銷燬的bean synchronized (this.disposableBeans) { disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); } // 根據註冊順序,倒着遍歷,銷燬bean for (int i = disposableBeanNames.length - 1; i >= 0; i--) { destroySingleton(disposableBeanNames[i]); } this.containedBeanMap.clear(); this.dependentBeanMap.clear(); this.dependenciesForBeanMap.clear(); // 從緩存中清除全部單例實例 clearSingletonCache(); } // DefaultSingletonBeanRegistry.java public void destroySingleton(String beanName) { // Remove a registered singleton of the given name, if any. // 從緩存中清除全部當前beanName單例實例 removeSingleton(beanName); // Destroy the corresponding DisposableBean instance. DisposableBean disposableBean; // 加鎖,從disposableBeans中將當前bean移除 synchronized (this.disposableBeans) { disposableBean = (DisposableBean) this.disposableBeans.remove(beanName); } // 銷燬bean destroyBean(beanName, disposableBean); } protected void destroyBean(String beanName, @Nullable DisposableBean bean) { // Trigger destruction of dependent beans first... Set<String> dependencies; // 加鎖,從dependentBeanMap中移除當前bean synchronized (this.dependentBeanMap) { // Within full synchronization in order to guarantee a disconnected Set dependencies = this.dependentBeanMap.remove(beanName); } if (dependencies != null) { if (logger.isTraceEnabled()) { logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); } // dependencies不爲空,說明,當前bean有其它依賴的bean,遍歷去銷燬 for (String dependentBeanName : dependencies) { destroySingleton(dependentBeanName); } } // Actually destroy the bean now... // bean不爲空,調用destroy方法真正的開始進行銷燬 if (bean != null) { try { bean.destroy(); } catch (Throwable ex) { if (logger.isWarnEnabled()) { logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex); } } } // Trigger destruction of contained beans... Set<String> containedBeans; synchronized (this.containedBeanMap) { // Within full synchronization in order to guarantee a disconnected Set containedBeans = this.containedBeanMap.remove(beanName); } if (containedBeans != null) { for (String containedBeanName : containedBeans) { destroySingleton(containedBeanName); } } // Remove destroyed bean from other beans' dependencies. synchronized (this.dependentBeanMap) { for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) { Map.Entry<String, Set<String>> entry = it.next(); Set<String> dependenciesToClean = entry.getValue(); dependenciesToClean.remove(beanName); if (dependenciesToClean.isEmpty()) { it.remove(); } } } // Remove destroyed bean's prepared dependency information. this.dependenciesForBeanMap.remove(beanName); }
public void destroy() { // 若是beanPostProcessors不爲空 if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { // 遍歷beanPostProcessors調用postProcessBeforeDestruction() for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { processor.postProcessBeforeDestruction(this.bean, this.beanName); } } if (this.invokeDisposableBean) { if (logger.isTraceEnabled()) { logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'"); } try { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this.bean).destroy(); return null; }, this.acc); } else { // 調用實現了DisposableBean的destroy() ((DisposableBean) this.bean).destroy(); } } catch (Throwable ex) { String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'"; if (logger.isDebugEnabled()) { logger.warn(msg, ex); } else { logger.warn(msg + ": " + ex); } } } // 調用自定義的destroy方法 if (this.destroyMethod != null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToInvoke = determineDestroyMethod(this.destroyMethodName); if (methodToInvoke != null) { invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke)); } } }
總得來講上面方法主要分爲三步:
回調實現了 DestructionAwareBeanPostProcessor
接口的 postProcessBeforeDestruction
方法,InitDestoryAnnotationBeanPostProcessor
的 postProcessBeforeDestruction()
中會執行標註了 @PreDestory
註解的方法。
調用實現了 DisposableBean
接口的 destroy()
。
調用自定義實現的 destroyMethod
,例如 XML 中的 destory
屬性指定的方法
本文主要介紹了 createBean()
流程,咱們能夠從新梳理一下思路:
bean
的實例化前方法回調,若是返回非空,跳事後面步驟bean
的實例,若是是構造函數注入會選擇最適合的構造函數進行參數自動注入,不然調用默認的無參構造進行實例化 bean
。bean
容許提早曝光,將 beanName
對應的 ObjectFactory
放入 singletonFactories
緩存中。bean
的屬性賦值階段,首先調用 bean
實例化後方法回調,返回 false
會跳事後面的賦值階段;判斷是不是按照名稱或者類型自動注入,是則進行屬性自動注入。接着調用處理屬性值的後置處理方法,首先調用Spring5.1版本新加的方法,若是返回的屬性爲空,再調用之前版本的方法,若是爲空,直接返回,不必再走後面的實際賦值階段。bean
的初始化階段,首先是調用能夠獲取相應資源的一些 Aware
接口;而後調用 bean
初始化前回調方法 ( InitDestroyAnnotationBeanPostProcessor
的 postProcessBeforeInitialization()
中會執行@PostConstruct
註解的方法),接着調用重寫的 afterPropertiesSet()
和自定義的初始化方法;最後進行 bean
初始化後回調方法。bean
的方法。bean
的實例。最後,我模仿 Spring 寫了一個精簡版,代碼會持續更新。地址:https://github.com/leisurexi/tiny-spring。訪問新博客地址,觀看效果更佳 https://leisurexi.github.io/