Spring IoC createBean 方法詳解

前言

本篇文章主要分析 Spring IoC 的 createBean() 方法的流程,以及 bean 的生命週期。java

下面是一個大體的流程圖:git

Spring IoC createBean 方法流程.png

正文

AbstractAutowireCapableBeanFactory#createBean

@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

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

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

AbstractAutowireCapableBeanFactory#doCreateBean

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;
}

AbstractAutowireCapableBeanFactory#createBeanInstance

/**
* @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 參數

AbstractAutowireCapableBeanFactory#instantiateBean

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

ConstructorResolver#autowireConstructor

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;
}

上面代碼的功能主要以下:函數

  1. 構造函數參數的肯定
    • 若是 explicitArgs 參數不爲空,那就能夠直接肯定參數。由於 explicitArgs 參數是在調用 getBean() 時手動指定的,這個主要用於靜態工廠方法的調用。
    • 緩存中不爲空,那麼能夠直接拿過來使用。
    • BeanDefinition 中讀取,咱們所定義的 bean 都會生成一個 BeanDefinition ,其中記錄了定義了構造函數參數經過 getConstructorArgumentValues() 獲取。
  2. 構造函數的肯定。通過第一步已經肯定構造函數的參數,接下來就是用參數個數在全部的構造函數中鎖定對應的構造函數。匹配以前會對構造函數進行排序,首先是 public 構造函數且參數個數從多到少,而後是非public 構造函數且參數個數有多到少。這樣能夠迅速判斷排在後面的構造函數參數個數是否符合條件。
  3. 根據對應的構造函數轉換對應的參數類型。
  4. 根據實例化策略以及獲得的構造函數和構造函數參數實例化 bean

ConstructorResolver#resolveConstructorArguments

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;
}

上面代碼主要將 indexedArgumentValuesgenericArgumentValues 的值調用 resolveValueIfNecessary() 進行解析;resolveValueIfNecessary() 主要解析參數的類型,好比 ref 屬性引用的 beanName 會經過 getBean() 返回實例。

ConstructorResolver#createArgumentArray

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 並返回實例。

ConstructorResolver#resolveAutowiredArgument

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() 這個方法,這個就是解決依賴注入的祕密所在。

DefaultListableBeanFactory#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 的類型是 OptionalObjectFactoryObjectProviderProvider 會作特殊的處理,通常狀況下注入的 bean 會走最後的 doResolveDependency()。 還有一個比較重要的參數 DependencyDescriptor,這個類就是依賴描述符,存儲了須要注入 bean 的類型、構造器參數的下標(構造器注入該值不爲空)、是否必需、字段名稱(字段注入該值不爲空)、方法名稱(setter 方法注入該值不爲空)等。

DefaultListableBeanFactory#doResolveDependency

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,大概分爲如下幾個步驟:

  1. 查看是否有快捷方式獲取注入 bean 是否爲空,不爲空直接返回。這裏的快捷方式是經過繼承 DependencyDescriptor 並重寫 resolveShortcut() 來實現。

  2. 若是參數使用 @Value 註解修飾了,若是獲取到值直接返回。

  3. 解析 MultipleBean,這裏的 MultipleBean 通常是 ArrayCollectionMap 這種,不爲空直接返回。

  4. 根據類型找到全部匹配的 beanmatchingBeanskeybeanNamevalue 的值有兩種狀況,若是bean已經緩存了實例(例如單例bean會緩存其實例),就是bean的實例,不然就是對應的class對象)。

  5. matchingBeans 爲空,判斷須要注入的 bean 是不是必須的,若是是拋出異常,不然返回 null

  6. matchingBeans 長度大於1,表明有多個候選者;選擇最佳的候選者,規則是:

    1. 首先查找 primary 屬性爲 true 的。
    2. 查找優先級最高的,實現 PriorityOrdered 接口或者標註 @Priority 註解的。
    3. 查找名稱匹配的。
  7. 只有一個候選者,直接使用。

  8. 若是須要注入的 bean 沒有緩存實例,那麼 instanceCandidate是一個 Class 對象,再根據 getBean() 去獲取對應的實例。

  9. 最終返回須要注入的 bean 實例。

AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors

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 合併後的方法回調,在這個回調方法內你能夠對指定 beanBeanDefinition 作一些修改。

下面咱們簡單看一下 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) {
        
    }

}

DefaultSingletonBeanRegistry#addSingletonFactory

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;
}

由於 beanAbeanB 中的 beanA 所表示的屬性地址是同樣的,因此在 beanA 中建立好的屬性填充天然能夠經過 beanB 中的 beanA 獲取,這樣就解決了循環依賴的問題。

AbstractAutowireCapableBeanFactory#getEarlyBeanReference

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,不作任何處理。

AbstractAutowireCapableBeanFactory#populateBean

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(),不然直接使用返回的 PropertyValuespostProcessPropertyValues() 若是返回空會直接跳過屬性填充階段,不爲空直接使用返回的 PropertyValues

AbstractAutowireCapableBeanFactory#autowireByName

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");
            }
        }
    }
}

AbstractAutowireCapableBeanFactory#autowireByType

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);
        }
    }
}

AbstractAutowireCapableBeanFactory#applyPropertyValues

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() 去給屬性賦值。

AbstractAutoCapableBeanFactory#initializeBean

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;
}

AbstractAutowireCapableBeanFactory#invokeAwareMethods

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 的被初始化以前,能夠取得一些相對應的資源,好比 beanNamebeanFactory 等。

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

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;
}

AbstractAutowireCapableBeanFactory#invokeInitMethods

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 初始化階段流程主要以下:

  1. @PostConstruct 註解修飾的方法,前提是註解驅動
  2. 實現 InitializingBean 接口的 afterPropertySet()
  3. 自定義初始化方法,例如 XML 中的 init-method 屬性設置的方法

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

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

AbstractBeanFactory#registerDisposableBeanIfNecessary

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));
        }
    }
}

DisposableBeanAdapter構造函數

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);
}

DisposableBeanAdapter#filterPostProcessors

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;
}

上面的代碼主要就是判斷若是 BeanPostProcessorDestructionAwareBeanPostProcessor 而且 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 實例是否要由此後置處理器進行實例的銷燬。

DefaultListableBeanFactory#destroySingletons

由於基本上 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);
}

DisposableBeanAdapter#destroy

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));
        }
    }
}

總得來講上面方法主要分爲三步:

  1. 回調實現了 DestructionAwareBeanPostProcessor 接口的 postProcessBeforeDestruction 方法,InitDestoryAnnotationBeanPostProcessorpostProcessBeforeDestruction() 中會執行標註了 @PreDestory 註解的方法。

  2. 調用實現了 DisposableBean 接口的 destroy()

  3. 調用自定義實現的 destroyMethod,例如 XML 中的 destory 屬性指定的方法

總結

本文主要介紹了 createBean() 流程,咱們能夠從新梳理一下思路:

  1. 進行 bean 的實例化前方法回調,若是返回非空,跳事後面步驟
  2. 建立 bean 的實例,若是是構造函數注入會選擇最適合的構造函數進行參數自動注入,不然調用默認的無參構造進行實例化 bean
  3. 若是 bean 容許提早曝光,將 beanName 對應的 ObjectFactory 放入 singletonFactories 緩存中。
  4. bean 的屬性賦值階段,首先調用 bean 實例化後方法回調,返回 false 會跳事後面的賦值階段;判斷是不是按照名稱或者類型自動注入,是則進行屬性自動注入。接着調用處理屬性值的後置處理方法,首先調用Spring5.1版本新加的方法,若是返回的屬性爲空,再調用之前版本的方法,若是爲空,直接返回,不必再走後面的實際賦值階段。
  5. bean 的初始化階段,首先是調用能夠獲取相應資源的一些 Aware 接口;而後調用 bean 初始化前回調方法 ( InitDestroyAnnotationBeanPostProcessorpostProcessBeforeInitialization() 中會執行
    標註了 @PostConstruct 註解的方法),接着調用重寫的 afterPropertiesSet() 和自定義的初始化方法;最後進行 bean 初始化後回調方法。
  6. 註冊銷燬 bean 的方法。
  7. 最後返回 bean 的實例。

最後,我模仿 Spring 寫了一個精簡版,代碼會持續更新。地址:https://github.com/leisurexi/tiny-spring。訪問新博客地址,觀看效果更佳 https://leisurexi.github.io/

參考

  • 《Spring 源碼深度解析》—— 郝佳
相關文章
相關標籤/搜索