Spring 生命周期二

151 阅读26分钟

Spring Bean 生命周期二

[TOC]

Chapter 6 Spring Bean 实例化阶段

1 AbstractAutowireCapableBeanFactory#doCreateBean

该方法为创建 Bean, createBeanInstance 则为创建 Bean 的实例的方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {

    // 实例化 bean。
    BeanWrapper instanceWrapper = null;
    // RootBeanDefinition 是单例作用域
    if (mbd.isSingleton()) {
        // 移除缓存,并返回移除对象
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // bean 的包装器 == null 
    if (instanceWrapper == null) {
        // 创建 Bean 的包装器
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    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 {
                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.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        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);
        }
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                            "Bean with name '" + beanName + "' has been injected into other beans [" +
                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                            "] in its raw version as part of a circular reference, but has eventually been " +
                            "wrapped. This means that said other beans do not use the final version of the " +
                            "bean. This is often the result of over-eager type matching - consider using " +
                            "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

2 AbstractAutowireCapableBeanFactory#createBeanInstance

determineConstructorsFromBeanPostProcessors 该方法作用为从扩展器列表中决定使用的构造器列表 用户可以自己去扩展 SmartInstantiationAwareBeanPostProcessor 接口,返回构造器列表 createBeanInstance 方法的参数解析:

  • String beanName bean 的名称
  • RootBeanDefinition mbd bean 定义
  • @Nullable Object[] args 构造参数列表,可以为空
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 通过 BeanClassName 去解析 Bean 对应的 Class
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    // 对类的权限做验证,如果不是 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());
    }
    
    // 函数式接口,先忽略
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }
    
    // RootBeanDefinition 是否配置了 工厂方法
    if (mbd.getFactoryMethodName() != null) {
        // 通过工厂方法进行实例创建
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    // 解析标识
    boolean resolved = false;
    boolean autowireNecessary = false;
    // 如果传入的构造参数为空
    if (args == null) {
        // 加锁
        synchronized (mbd.constructorArgumentLock) {
            // 解析过后的构造方法或者工厂方法是否为空
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                // 解析标识变为 true
                resolved = true;
                // 是否需要自动注入
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    // 是否已经解析过
    // resolved == true 的场景为,当类的作用域为 prototype 时,重复去依赖查找或者依赖注入时,都是获取新的对象,
    // 但是 Bean 定义都是不变的,这里直接进行之前的解析情况进行 Bean 的实例化
    // 减少了构造参数的确定,性能优化
    if (resolved) {
        if (autowireNecessary) {
            // 通过构造参数自动创建
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            // 默认的无参构造创建 Bean 实例
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    // 从 Bean 的扩展中去确定构造器列表
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // ctors != null 构造方法不为空 
    // mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR  解析模式为构造器自动注入
    // mbd.hasConstructorArgumentValues() 有构造器参数
    // !ObjectUtils.isEmpty(args) 传递的构造器参数不为空
    // 以上四种情况都会走入构造器注入
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 根据构造器自主注入
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    // 前面都没有获取到构造器,这里选择默认的构造器
    ctors = mbd.getPreferredConstructors();
    // 如果找到了构造器
    if (ctors != null) {
        // 根据构造器自动装配
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    // 普通的 Bean 实例化
    return instantiateBean(beanName, mbd);
}


3 AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors

/**
 * 确定用于给定 bean 的候选构造函数,检查所有已注册的
 */
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
        throws BeansException {

    if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
                if (ctors != null) {
                    return ctors;
                }
            }
        }
    }
    return null;
}

4 AbstractAutowireCapableBeanFactory#instantiateBean

getInstantiationStrategy 获取实例化策略。

InstantiationStrategy 是实例化的策略接口,策略的实现为: CglibSubclassingInstantiationStrategy 和 SimpleInstantiationStrategy, CglibSubclassingInstantiationStrategy 策略又继承了 SimpleInstantiationStrategy 类。 这里调用 instantiationStrategy#instantiate 方法,但是 CglibSubclassingInstantiationStrategy 中没有重写 instantiate 方法,所以,调用的还是 SimpleInstantiationStrategy 中的实例化方法

	/** 创建 bean 实例的策略。默认采用 CGLIB 策略 */
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        // Java 安全管理
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                    getInstantiationStrategy().instantiate(mbd, beanName, parent),
                    getAccessControlContext());
        }
        else {
            // 根据相应的策略类去创建 Bean 实例
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        }
        // 将 bean 实例 转化为 Bean 包装类
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        // 初始化 Bean 的包装类
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

5 SimpleInstantiationStrategy#instantiate

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    // 不存在方法定义的覆盖   
    if (!bd.hasMethodOverrides()) {
        Constructor<?> constructorToUse;
        synchronized (bd.constructorArgumentLock) {
            // 获取 RootBeanDefinition 的解析构造器或者工厂方法
            // 首次进来为空
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
                // 获取 beanClass
                final Class<?> clazz = bd.getBeanClass();
                // 如果 beanClass 为接口,则抛出异常
                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 = bean 的构造器
                        constructorToUse = clazz.getDeclaredConstructor();
                    }
                    // 再赋值给 resolvedConstructorOrFactoryMethod
                    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.
        // 走方法注入
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

6 BeanUtils#instantiateClass

BeanUtils Bean 操作的工具类

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
    try {
        // 设置构造器的权限为true
        ReflectionUtils.makeAccessible(ctor);
        if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
            return KotlinDelegate.instantiateClass(ctor, args);
        }
        else {
            // 获取参数的类型列表
            Class<?>[] parameterTypes = ctor.getParameterTypes();
            Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
            // 创建参数数组
            Object[] argsWithDefaultValues = new Object[args.length];
            for (int i = 0 ; i < args.length; i++) {
                // 如果参数为空
                if (args[i] == null) {
                    // 获取参数的类型
                    Class<?> parameterType = parameterTypes[i];
                    // 如果是包装类,则为null,如果是基础类型,则为对应包装类型的默认值
                    argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
                }
                else {
                    // 不为空的情况下直接赋值
                    argsWithDefaultValues[i] = args[i];
                }
            }
            // 调用反射创建 Bean 的实例
            return ctor.newInstance(argsWithDefaultValues);
        }
    }
    catch (InstantiationException ex) {
        throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
    }
    catch (IllegalAccessException ex) {
        throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
    }
    catch (IllegalArgumentException ex) {
        throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
    }
    catch (InvocationTargetException ex) {
        throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
    }
}

7 AbstractAutowireCapableBeanFactory#autowireConstructor

构造器注入方法,这里创建了一个构造器处理器来执行自动注入操作

protected BeanWrapper autowireConstructor(
        String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

    return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

8 ConstructorResolver#autowireConstructor

参数解析:

  • String beanName bean名称
  • RootBeanDefinition mbd bean定义
  • @Nullable Constructor<?>[] chosenCtors 从 BeanPostProcessors 中获取的构造器列表
  • @Nullable Object[] explicitArgs XML 中配置的 里面配置的参数
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
        @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
    // 创建 Bean 的包装器
    BeanWrapperImpl bw = new BeanWrapperImpl();
    // 初始化 Bean 的包装器
    this.beanFactory.initBeanWrapper(bw);
    
    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    // 显示的构造器参数(即 XML 中配置的)
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    }
    else {
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            // 获取 RootBeanDefinition 上的已经解析好的构造方法或者工厂方法,首次为 null
            constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                // Found a cached constructor...
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        // 
        if (argsToResolve != null) {
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
        }
    }

    // 需要用的构造器和构造器参数都为空的时候执行
    if (constructorToUse == null || argsToUse == null) {
        //采用指定的构造函数,如果有的话。
        Constructor<?>[] candidates = chosenCtors;
        // 指定构造器为空
        if (candidates == null) {
            // 获取 beanClass
            Class<?> beanClass = mbd.getBeanClass();
            try {
                // 返回是否允许访问非公共构造函数和方法 ? 获取所有构造方法 : 获取所有 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);
            }
        }

        // 只有一个构造器候选者 && 没有设置构造器参数 && 拥有构造器标识也为 null
        if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
            // 获取唯一的构造器
            Constructor<?> uniqueCandidate = candidates[0];
            // 如果构造器没有参数
            if (uniqueCandidate.getParameterCount() == 0) {
                synchronized (mbd.constructorArgumentLock) {
                    // 将构造器添加到已经解析的构造器或者工厂方法记录中
                    mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                    // 构造器参数已经解析标识更新
                    mbd.constructorArgumentsResolved = true;
                    // 赋值构造器参数
                    mbd.resolvedConstructorArguments = EMPTY_ARGS;
                }
                // 设置实例
                bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
                return bw;
            }
        }

        // 当传递的构造器列表存在或者 RootBeanDefinition 的类型为构造器自动注入时,需要解析构造函数。
        boolean autowiring = (chosenCtors != null ||
                mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
        // 构造器参数列表
        ConstructorArgumentValues resolvedValues = null;

        int minNrOfArgs;
        // 存在显示的构造器参数
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        }
        else {
            // 
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            resolvedValues = new ConstructorArgumentValues();
            // 将此 bean 的构造函数参数解析为 resolvedValues 对象。这可能涉及查找其他 bean
            // 参数的最小长度
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }
        
        // 将构造器进行排序
        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);
                    if (paramNames == null) {
                        // 从参数名称发现器中获取 beanName
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            // 获取参数名称
                            paramNames = pnd.getParameterNames(candidate);
                        }
                    }
                    // 创建参数数组
                    argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                            getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
                }
                catch (UnsatisfiedDependencyException ex) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
                    }
                    // Swallow and try next constructor.
                    if (causes == null) {
                        causes = new LinkedList<>();
                    }
                    causes.add(ex);
                    continue;
                }
            }
            else {
                // Explicit arguments given -> arguments length must match exactly.
                if (parameterCount != explicitArgs.length) {
                    continue;
                }
                argsHolder = new ArgumentsHolder(explicitArgs);
            }
            
            // 返回是在宽松模式还是在严格模式下解析构造函数。
            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                    argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // 如果它代表最接近的匹配,则选择此构造函数。
            if (typeDiffWeight < minTypeDiffWeight) {
                // 构造器赋值
                constructorToUse = candidate;
                // 构造器包装参数赋值
                argsHolderToUse = argsHolder;
                argsToUse = argsHolder.arguments;
                minTypeDiffWeight = typeDiffWeight;
                ambiguousConstructors = null;
            }
            else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                if (ambiguousConstructors == null) {
                    ambiguousConstructors = new LinkedHashSet<>();
                    ambiguousConstructors.add(constructorToUse);
                }
                ambiguousConstructors.add(candidate);
            }
        }

        if (constructorToUse == null) {
            if (causes != null) {
                UnsatisfiedDependencyException ex = causes.removeLast();
                for (Exception cause : causes) {
                    this.beanFactory.onSuppressedException(cause);
                }
                throw ex;
            }
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Could not resolve matching constructor " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
        }
        else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Ambiguous constructor matches found in bean '" + beanName + "' " +
                    "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                    ambiguousConstructors);
        }

        if (explicitArgs == null && argsHolderToUse != null) {
            argsHolderToUse.storeCache(mbd, constructorToUse);
        }
    }

    Assert.state(argsToUse != null, "Unresolved constructor arguments");
    // bean 包装器设置实例 
    bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
    return bw;
}

9 ConstructorPropertiesChecker#evaluate

private static class ConstructorPropertiesChecker {

    @Nullable
    public static String[] evaluate(Constructor<?> candidate, int paramCount) {
        // 构造器上获取 ConstructorProperties 注解
        ConstructorProperties cp = candidate.getAnnotation(ConstructorProperties.class);
        // 如果找到了
        if (cp != null) {
            // 获取结果
            String[] names = cp.value();
            if (names.length != paramCount) {
                throw new IllegalStateException("Constructor annotated with @ConstructorProperties but not " +
                        "corresponding to actual number of parameters (" + paramCount + "): " + candidate);
            }
            return names;
        }
        else {
            // 返回空
            return null;
        }
    }
}

10 PrioritizedParameterNameDiscoverer#getParameterNames

@Override
@Nullable
public String[] getParameterNames(Constructor<?> ctor) {
    for (ParameterNameDiscoverer pnd : this.parameterNameDiscoverers) {
        String[] result = pnd.getParameterNames(ctor);
        if (result != null) {
            return result;
        }
    }
    return null;
}

11 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 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).
            if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
                valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
            }
        }
        if (valueHolder != null) {
            // We found a potential match - let's give it a try.
            // Do not consider the same value definition multiple times!
            usedValueHolders.add(valueHolder);
            Object originalValue = valueHolder.getValue();
            Object convertedValue;
            if (valueHolder.isConverted()) {
                convertedValue = valueHolder.getConvertedValue();
                args.preparedArguments[paramIndex] = convertedValue;
            }
            else {
                // 如果是构造方法,则添加构造方法参数,如果是普通方法,则添加普通方法参数
                MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                try {
                    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.resolveNecessary = true;
                    args.preparedArguments[paramIndex] = sourceValue;
                }
            }
            args.arguments[paramIndex] = convertedValue;
            args.rawArguments[paramIndex] = originalValue;
        }
        else {
            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 {
                // 解析自动注入的对象,会调用依赖注入去找到构造方法对应的参数对象,会优先获取 primary 标注的对象
                Object autowiredArgument = resolveAutowiredArgument(
                        methodParam, beanName, autowiredBeanNames, converter, fallback);
                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);
            }
        }
    }

    for (String autowiredBeanName : autowiredBeanNames) {
        // 为给定的bean注册一个依赖bean,*在给定的bean被销毁之前被销毁
        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;
}

12 ConstructorResolver#resolveAutowiredArgument

用于解析应该自动装配的指定参数的模板方法

/**
 * Template method for resolving the specified argument which is supposed to be autowired.
 */
@Nullable
protected Object resolveAutowiredArgument(MethodParameter param, String beanName,
        @Nullable Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {
    // 获取参数类型
    Class<?> paramType = param.getParameterType();
    if (InjectionPoint.class.isAssignableFrom(paramType)) {
        InjectionPoint injectionPoint = currentInjectionPoint.get();
        if (injectionPoint == null) {
            throw new IllegalStateException("No current InjectionPoint available for " + param);
        }
        return injectionPoint;
    }
    try {
        // 调用 beanFactory 的 resolveDependency 方法,该方法在前面的章节中已经讲过,可以回顾到之前的章节
        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;
    }
}

Chapter 7 Spring Bean 实例化后阶段

1 实例化后扩展阶段

实现 InstantiationAwareBeanPostProcessor 接口,并重写 postProcessAfterInstantiation 方法,该方法有两个参数:

  • Object bean 当前正在创建的 Bean
  • String beanName bean 的名称
  • Return boolean 如果该值返回的是 false,则代表当前 bean 在后续不需要进行属性值的填充,在该方法中进行填充,如果返回的是 true,则继续执行后续填充属性的流程。
package com.geekbang.thinking.in.spring.bean.lifecycle;

import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.util.ObjectUtils;

/**
 * @ClassName BeforeInstantiationBeanLifeCycleDemo
 * @Description {@link InstantiationAwareBeanPostProcessor}实例化前阶段使用案例展示
 * @Author WQ
 * @Date 2022/8/11 18:05
 * @Version 1.0
 */
public class InstantiationBeanLifeCycleDemo {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new ChildUserInstantiationAwareBeanPostProcessor());
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
        reader.loadBeanDefinitions(locations);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
        SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
        System.out.println(superUser);
        UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
        System.out.println(userHolder);
    }

    static class ChildUserInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//            if (ObjectUtils.nullSafeEquals("superUser", beanName) && beanClass.equals(SuperUser.class)) {
//                ChildUser childUser = new ChildUser();
//                childUser.setAge(22);
//                return childUser;
//            }
            return null;
        }

        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass().equals(User.class)) {
                User user = (User) bean;
                user.setId(815L);
                user.setName("小幸运");
                return false;
            }
            return true;
        }
    }
}

2 postProcessAfterInstantiation 源码分析

  • mbd.isSynthetic() 这里会判断 bean 是否为应用系统所创建, 一般为 false。
  • hasInstantiationAwareBeanPostProcessors() 是否具有 AwareBeanPostProcessors 扩展实现。 ibp.postProcessAfterInstantiation 调用扩展实现的方法,如果返回的是 false 则直接结束 populateBean() 方法,结束赋值阶段。 返回 true 则继续向下执行 populateBean 执行属性赋值。

该源码分析在 AbstractAutowireCapableBeanFactory#populateBean 方法中进行属性填充的部分代码片段

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }
}

Chapter 8 Spring Bean 属性赋值前阶段

1 概述

Bean 属性值元信息

  • PropertyValues 属性的元信息,即存储属性值,在构造器里的话就是 ConstructorValues Bean 属性赋值前回调
  • Spring 1.2 - 5.0:InstantiationAwareBeanPostProcessor#postProcessPropertyValues
  • Spring 5.1:InstantiationAwareBeanPostProcessor#postProcessProperties

2 属性赋值前阶段,修改属性值示例

该声明周期主要处于实例化对象后阶段,属性赋值前阶段的中间阶段。 主要作用为:可以提前修改配置的属性,这样在属性赋值时,就不会采用配置的属性。 注意事项:如果在实例化对象后阶段,已经返回 false,终止掉了后续属性赋值流程,则 postProcessProperties 方法并不会被调用。

package com.geekbang.thinking.in.spring.bean.lifecycle;

import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.util.ObjectUtils;

/**
 * @ClassName BeforeInstantiationBeanLifeCycleDemo
 * @Description {@link InstantiationAwareBeanPostProcessor}实例化前阶段使用案例展示
 * @Author WQ
 * @Date 2022/8/11 18:05
 * @Version 1.0
 */
public class InstantiationBeanLifeCycleDemo {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new ChildUserInstantiationAwareBeanPostProcessor());
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
        reader.loadBeanDefinitions(locations);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
        SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
        System.out.println(superUser);
        UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
        System.out.println(userHolder);
    }

    static class ChildUserInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//            if (ObjectUtils.nullSafeEquals("superUser", beanName) && beanClass.equals(SuperUser.class)) {
//                ChildUser childUser = new ChildUser();
//                childUser.setAge(22);
//                return childUser;
//            }
            return null;
        }

        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass().equals(User.class)) {
                User user = (User) bean;
                user.setId(815L);
                user.setName("小幸运");
                return false;
            }
            return true;
        }

        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            if (ObjectUtils.nullSafeEquals("userHolder", beanName) && bean.getClass().equals(UserHolder.class)){
                final MutablePropertyValues propertyValues;
                if (pvs instanceof MutablePropertyValues) {
                    propertyValues = (MutablePropertyValues) pvs;
                } else {
                    propertyValues = new MutablePropertyValues();
                }
                propertyValues.add("number", "1111");
                propertyValues.removePropertyValue("description");
                propertyValues.addPropertyValue("description", "this is a description V2");
                return propertyValues;
            }
            return null;
        }
    }
}

3 AbstractAutowireCapableBeanFactory#populateBean

AbstractAutowireCapableBeanFactory#populateBean 部分代码段实现了 Spring Bean 属性赋值前阶段对属性的修改操作 实例化后阶段,如果 postProcessAfterInstantiation 方法返回了 false, 则 populateBean Bean 属性填充就此结束。

@SuppressWarnings("deprecation")  // for postProcessPropertyValues
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.
    // 如果这里 postProcessAfterInstantiation 方法返回了 false, 属性填充就终止掉了
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    }

    // 获取 PropertyValues 属性元信息
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    // 解析自动注入模式(1-根据名称、2-根据类型、3-根据构造器)
    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();
        }
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // Bean 属性赋值前阶段,如果返回的 PropertyValues 有值,代表该方法已经修改了属性值
                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);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
    }
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
        // 运行属性值填充 Bean 实例
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

Chapter 9 Spring Bean Aware接口回调阶段

1 概述

Spring Aware 接口

  • BeanNameAware
  • BeanClassLoaderAware
  • BeanFactoryAware
  • EnvironmentAware
  • EmbeddedValueResolverAware
  • ResourceLoaderAware
  • ApplicationEventPublisherAware
  • MessageSourceAware
  • ApplicationContextAware

Aware 接口是 Spring 提供的回调接口,该接口只能使用 Spring 已存在的扩展,不允许用户自己扩展。 以 BeanNameAware 接口来说,该接口可以回调注入 BeanName。 BeanFactoryAware 则可以回调注入一个 BeanFactory

2 UserHolder

需要注入 Spring 中的 Bean, 实现了 BeanFactory 的 Aware 接口和 ApplicationContext 所属下的 Aware 接口。

package com.geekbang.thinking.in.spring.bean.lifecycle.domain;

import com.geekbang.spring.ioc.container.overview.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.config.EmbeddedValueResolver;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.StringValueResolver;

/**
 * @ClassName UserHolder
 * @Description TODO
 * @Author WQ
 * @Date 2022/8/12 14:46
 * @Version 1.0
 */
public class UserHolder implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware {

    private User user;

    private Integer number;

    private String description;

    private String beanName;

    private ClassLoader classLoader;

    private BeanFactory beanFactory;

    private EmbeddedValueResolver resolver;

    private Environment environment;

    private ResourceLoader resourceLoader;

    public UserHolder(User user) {
        this.user = user;
    }


    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }


    @Override
    public String toString() {
        return "UserHolder{" +
                "user=" + user +
                ", number=" + number +
                ", description='" + description + '\'' +
                ", beanName='" + beanName + '\'' +
                ", classLoader=" + classLoader +
                ", beanFactory=" + beanFactory +
                ", resolver=" + resolver +
                ", environment=" + environment +
                ", resourceLoader=" + resourceLoader +
                '}';
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }


    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.resolver = (EmbeddedValueResolver) resolver;
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }
}

3 AbstractAutowireCapableBeanFactory#initializeBean

initializeBean 是初始化 Bean, 在创建 Bean 实例 createInstance(); 和 填充 bean 实例 populateBean(); 两个大的生命周期之后。 初始化 Bean 进行的第一步操作是执行 Aware 回调方法。该方法会给实现了 Aware 接口的对象注入相应的属性。

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 {
        // 执行 Aware 回调方法
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 执行 ApplicationContext 类型的 Aware 回调接口
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        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()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

4 AbstractAutowireCapableBeanFactory#invokeAwareMethods

执行 Aware 回调方法,执行顺序为:BeanName --> BeanClassLoader --> BeanFactory。

private void invokeAwareMethods(final String beanName, final Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

5 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

在初始化 Bean 前运行 BeanPostProcessors。 postProcessBeforeInitialization 执行初始化前的扩展方法

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    // 遍历所有的 BeanPostProcessors
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 执行 postProcessBeforeInitialization 回调方法
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

6 ApplicationContextAwareProcessor#postProcessBeforeInitialization

postProcessBeforeInitialization 该方法当前分析的 Aware 接口处于 ApplicationContextAwareProcessor 实现类中,所以,我们的 beanFactory 也需要为 ApplicationContext 类型才可以。

@Override
	@Nullable
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
			return bean;
		}

		AccessControlContext acc = null;

		if (System.getSecurityManager() != null) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
		    // 执行 Aware 接口列表
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

7 ApplicationContextAwareProcessor#invokeAwareInterfaces

执行 ApplicationContext 类型的 Aware 接口回调方法 属性注入顺序即下面的添加顺序

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    }
    if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    }
    if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    }
    if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    }
    if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    }
    if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    }
}

8 Aware 接口回调注入属性示例

package com.geekbang.thinking.in.spring.bean.lifecycle;

import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ClassName BeforeInstantiationBeanLifeCycleDemo
 * @Description {@link InstantiationAwareBeanPostProcessor}实例化前阶段使用案例展示
 * @Author WQ
 * @Date 2022/8/11 18:05
 * @Version 1.0
 */
public class InstantiationBeanLifeCycleDemo {

    public static void main(String[] args) {
        executeBeanFactory();
        executeApplicationContext();
    }

    private static void executeApplicationContext() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
        String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
        applicationContext.setConfigLocations(locations);
        applicationContext.refresh();
        User user = applicationContext.getBean("user", User.class);
        System.out.println(user);
        SuperUser superUser = applicationContext.getBean("superUser", SuperUser.class);
        System.out.println(superUser);
        UserHolder userHolder = applicationContext.getBean("userHolder", UserHolder.class);
        System.out.println(userHolder);
        applicationContext.close();

    }

    private static void executeBeanFactory() {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//        beanFactory.addBeanPostProcessor(new ChildUserInstantiationAwareBeanPostProcessor());
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
        reader.loadBeanDefinitions(locations);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
        SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
        System.out.println(superUser);
        UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
        System.out.println(userHolder);
    }


}


Chapter 10 Spring Bean 初始化前阶段

1 概述

在前面的章节中 Bean 创建已完成如下步骤

  • Bean 实例化
  • Bean 属性赋值
  • Bean Aware 接口回调

接下来为方法回调

  • BeanPostProcessor#postProcessBeforeInitialization

2 applyBeanPostProcessorsBeforeInitialization

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        // 返回 null,则返回原始对象
        if (current == null) {
            return result;
        }
        // 否则替换为当前对象
        result = current;
    }
    // 返回对象
    return result;
}

3 SpringLifeCycleBeanPostProcessor 添加 BeanPostProcessors

postProcessBeforeInitialization 初始化前阶段回调

package com.geekbang.thinking.in.spring.bean.lifecycle;

import com.geekbang.spring.ioc.container.overview.domain.ChildUser;
import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.util.ObjectUtils;

/**
 * @ClassName ChildUserInstantiationAwareBeanPostProcessor
 * @Description TODO
 * @Author WQ
 * @Date 2022/8/15 15:57
 * @Version 1.0
 */
public class SpringLifeCycleBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("superUser", beanName) && beanClass.equals(SuperUser.class)) {
            ChildUser childUser = new ChildUser();
            childUser.setAge(22);
            return childUser;
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
//            if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass().equals(User.class)) {
//                User user = (User) bean;
//                user.setId(815L);
//                user.setName("小幸运");
//                return false;
//            }
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && bean.getClass().equals(UserHolder.class)){
            final MutablePropertyValues propertyValues;
            if (pvs instanceof MutablePropertyValues) {
                propertyValues = (MutablePropertyValues) pvs;
            } else {
                propertyValues = new MutablePropertyValues();
            }
            propertyValues.add("number", "1111");
            propertyValues.removePropertyValue("description");
            propertyValues.addPropertyValue("description", "this is a description V2");
            return propertyValues;
        }
        return null;
    }


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals(beanName, "user") && bean.getClass().equals(User.class)) {
            return null;
        }
        return bean;
    }
}

4 postProcessBeforeInitialization 使用示例

package com.geekbang.thinking.in.spring.bean.lifecycle;

import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ClassName BeanInitializationDemo
 * @Description Bean 初始化生命周期示例
 * @Author WQ
 * @Date 2022/8/15 17:47
 * @Version 1.0
 */
public class BeanInitializationLifeCycleDemo {


    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
        String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
        applicationContext.setConfigLocations(locations);
        applicationContext.refresh();
        User user = applicationContext.getBean("user", User.class);
        System.out.println(user);
        SuperUser superUser = applicationContext.getBean("superUser", SuperUser.class);
        System.out.println(superUser);
        UserHolder userHolder = applicationContext.getBean("userHolder", UserHolder.class);
        System.out.println(userHolder);
        applicationContext.close();
    }
}

Chapter 11 Spring Bean 初始化阶段

1 概述

Bean 初始化(Initialization)

  • @PostConstruct 标注方法
  • 实现 InitializingBean 接口的 afterPropertiesSet() 方法
  • 自定义初始化方法

2 @PostConstruct 注解解析

@PostConstruct 需要注解驱动,PostConstruct 的 注入是在 以下代码段中,所以 PostConstruct 注解要生效,需要beanFactory 具有CommonAnnotationBeanPostProcessor 这个 BeanPostProcessor 的能力。

public CommonAnnotationBeanPostProcessor() {
    setOrder(Ordered.LOWEST_PRECEDENCE - 3);
    setInitAnnotationType(PostConstruct.class);
    setDestroyAnnotationType(PreDestroy.class);
    ignoreResourceType("javax.xml.ws.WebServiceContext");
}

通过 @PostConstruct 添加 Bean 的初始化能力 示例

如果 beanFactory 不具有 CommonAnnotationBeanPostProcessor 的能力,可以调用如下 API 加入

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());

UserHolder 中通过 @PostConstruct 添加初始化方法

public class UserHolder {
    @PostConstruct
    public void initPostConstruct() {
        this.description = "this is a description V3";
        System.out.println("initPostConstruct() : this.description" + this.description);
    }
}

3 InitializingBean 接口的 afterPropertiesSet()方法分析

需要初始化的类需要实现 InitializingBean 并重写 afterPropertiesSet 方法,可以在该方法中对对象的属性值做修改,完成初始化操作。

public class UserHolder implements InitializingBean{

    @Override
    public void afterPropertiesSet() throws Exception {
        this.description = "this is a description V4";
        System.out.println("afterPropertiesSet() : this.description" + this.description);
    }
}

4 自定义初始化方法

自定义初始化方法需要我们在需要初始化的 Bean 对象内部添加初始化方法

public void init () {
    this.description = "this is a description V5";
    System.out.println("init() : this.description" + this.description);
}

并到 XML 中添加相应初始化方法配置,配置如下

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="userHolder" class="com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder" autowire="constructor" init-method="init" >
        <property name="description" value="this is a description V1" />

    </bean>
    <bean class="com.geekbang.thinking.in.spring.bean.lifecycle.SpringLifeCycleBeanPostProcessor"/>
</beans>

5 完整示例-需要初始化的 Bean UserHolder

package com.geekbang.thinking.in.spring.bean.lifecycle.domain;

import com.geekbang.spring.ioc.container.overview.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.EmbeddedValueResolver;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.StringValueResolver;

import javax.annotation.PostConstruct;

/**
 * @ClassName UserHolder
 * @Description TODO
 * @Author WQ
 * @Date 2022/8/12 14:46
 * @Version 1.0
 */
public class UserHolder implements InitializingBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware {

    private User user;

    private Integer number;

    private String description;

    private String beanName;

    private ClassLoader classLoader;

    private BeanFactory beanFactory;

    private EmbeddedValueResolver resolver;

    private Environment environment;

    private ResourceLoader resourceLoader;

    public UserHolder(User user) {
        this.user = user;
    }


    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }


    @Override
    public String toString() {
        return "UserHolder{" +
                "user=" + user +
                ", number=" + number +
                ", description='" + description + '\'' +
                ", beanName='" + beanName + '\'' +
                ", classLoader=" + classLoader +
                ", beanFactory=" + beanFactory +
                ", resolver=" + resolver +
                ", environment=" + environment +
                ", resourceLoader=" + resourceLoader +
                '}';
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }


    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.resolver = (EmbeddedValueResolver) resolver;
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }


    @PostConstruct
    public void initPostConstruct() {
        this.description = "this is a description V3";
        System.out.println("initPostConstruct() : this.description" + this.description);
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        this.description = "this is a description V4";
        System.out.println("afterPropertiesSet() : this.description" + this.description);
    }


    public void init() {
        this.description = "this is a description V5";
        System.out.println("init() : this.description" + this.description);
    }
}

6 完整示例:XML配置

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="userHolder" class="com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder" autowire="constructor" init-method="init" >
        <property name="description" value="this is a description V1" />

    </bean>

    <bean class="com.geekbang.thinking.in.spring.bean.lifecycle.SpringLifeCycleBeanPostProcessor"/>


</beans>

7 完整示例:获取对象,走初始化流程

package com.geekbang.thinking.in.spring.bean.lifecycle;

import com.geekbang.spring.ioc.container.overview.domain.SuperUser;
import com.geekbang.spring.ioc.container.overview.domain.User;
import com.geekbang.thinking.in.spring.bean.lifecycle.domain.UserHolder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ClassName BeanInitializationDemo
 * @Description Bean 初始化生命周期示例
 * @Author WQ
 * @Date 2022/8/15 17:47
 * @Version 1.0
 */
public class BeanInitializationLifeCycleDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
        String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions(locations);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
        SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
        System.out.println(superUser);
        UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
        System.out.println(userHolder);
    }
}

8 源码分析一:@PostConstruct

在初始化 bean 的方法中执行了初始化回调方法,在初始化前阶段的 BeanPostProcessors 回调中已经执行了 @PostConstruct 初始化方法。 代码分析如下:

applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

该方法在初始化之前运用所有的 BeanPostProcessors

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {
    	
    Object result = existingBean;
    // 遍历所有的 BeanPostProcessor
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
	// 执行 postProcessBeforeInitialization 方法
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

由于 @PostConstruct 在 CommonAnnotationBeanPostProcessor 中,并且该类继承了 InitDestroyAnnotationBeanPostProcessor 类,CommonAnnotationBeanPostProcessor 中没有重写 postProcessBeforeInitialization 方法,所以,直接看 InitDestroyAnnotationBeanPostProcessor 中的 postProcessBeforeInitialization 方法

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 寻找生命周期元信息
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        // 根据生命周期元信息执行初始化方法
        metadata.invokeInitMethods(bean, beanName);
    }
    catch (InvocationTargetException ex) {
        throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
    }
    return bean;
}

这里我们在回顾一下 findLifecycleMetadata 寻找生命周期元信息的方法,该方法主要作用为构建缓存

private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
    if (this.lifecycleMetadataCache == null) {
        // Happens after deserialization, during destruction...
        return buildLifecycleMetadata(clazz);
    }
    // Quick check on the concurrent map first, with minimal locking.
    LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
    if (metadata == null) {
        synchronized (this.lifecycleMetadataCache) {
            metadata = this.lifecycleMetadataCache.get(clazz);
            if (metadata == null) {
                // 构建生命周期元信息
                metadata = buildLifecycleMetadata(clazz);
                this.lifecycleMetadataCache.put(clazz, metadata);
            }
            return metadata;
        }
    }
    return metadata;
}

buildLifecycleMetadata 是从当前类开始找,递归查父类,找寻标注了 @PostConstruct 注解的方法

private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
    if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
        return this.emptyLifecycleMetadata;
    }

    List<LifecycleElement> initMethods = new ArrayList<>();
    List<LifecycleElement> destroyMethods = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<LifecycleElement> currInitMethods = new ArrayList<>();
        final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
        
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
                LifecycleElement element = new LifecycleElement(method);
                currInitMethods.add(element);
                if (logger.isTraceEnabled()) {
                    logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
                }
            }
            if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
                currDestroyMethods.add(new LifecycleElement(method));
                if (logger.isTraceEnabled()) {
                    logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
                }
            }
        });

        initMethods.addAll(0, currInitMethods);
        destroyMethods.addAll(currDestroyMethods);
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
            new LifecycleMetadata(clazz, initMethods, destroyMethods));
}

回顾了寻找生命周期元信息以后,继续执行初始化方法 invokeInitMethods

public void invokeInitMethods(Object target, String beanName) throws Throwable {
    Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
    Collection<LifecycleElement> initMethodsToIterate =
            (checkedInitMethods != null ? checkedInitMethods : this.initMethods);
    if (!initMethodsToIterate.isEmpty()) {
        for (LifecycleElement element : initMethodsToIterate) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
            }
            // 调用反射执行 @PostConstruct 标注的方法
            element.invoke(target);
        }
    }
}

9 源码分析二: InitializingBean 接口与自定义初始化方法

在 initializeBean 方法中会去执行

invokeInitMethods(beanName, wrappedBean, mbd);

invokeInitMethods 做了两件事情:

  1. 执行的初始化方法为实现了 InitializingBean 接口的方法。
  2. 执行用户自定义的初始化方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {
    // 判断是否为 InitializingBean 实例
    boolean isInitializingBean = (bean instanceof InitializingBean);
    // 判断是否为 InitializingBean 实例并且重写 afterPropertiesSet 方法
    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();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        // 从 RootBeanDefinition 上获取初始化方法
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 执行用户自定义的初始化方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

10 源码分析三:三个初始化方法的执行顺序

在初始化方法中, @PostConstruct 注解标注的初始化方法在初始化执行运行 BeanPostProcessor 就已经执行,而 invokeInitMethods 方法中先执行实现了 InitializingBean 接口中的初始化方法,再执行用户自定义的初始化方法。 最终的结论为: @PostConstruct --> 实现 InitializingBean 接口的初始化方法 --> 用户自定义的初始化方法

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 {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        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()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

Chapter 12 Spring Bean 初始化后阶段

1 概述

方法回调

  • BeanPostProcessor#postProcessAfterInitialization

初始化后阶段回调, 该回调可以再次修改 Bean 的属性值。

实现示例: 需要实现 BeanPostProcessor 并且重写 postProcessAfterInitialization 接口。

public class SpringLifeCycleBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("superUser", beanName) && beanClass.equals(SuperUser.class)) {
            ChildUser childUser = new ChildUser();
            childUser.setAge(22);
            return childUser;
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
//            if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass().equals(User.class)) {
//                User user = (User) bean;
//                user.setId(815L);
//                user.setName("小幸运");
//                return false;
//            }
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && bean.getClass().equals(UserHolder.class)){
            final MutablePropertyValues propertyValues;
            if (pvs instanceof MutablePropertyValues) {
                propertyValues = (MutablePropertyValues) pvs;
            } else {
                propertyValues = new MutablePropertyValues();
            }
            propertyValues.add("number", "1111");
            propertyValues.removePropertyValue("description");
            propertyValues.addPropertyValue("description", "this is a description V2");
            return propertyValues;
        }
        return null;
    }


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals(beanName, "user") && bean.getClass().equals(User.class)) {
            return null;
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals(beanName, "userHolder") && bean.getClass().equals(UserHolder.class)) {
            UserHolder userHolder = (UserHolder) bean;
            userHolder.setDescription("this is a description V6");
        }
        return null;
    }
}

Bean 初始化后阶段生命周期示例

public class BeanInitializationLifeCycleDemo {


    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());
        // 添加 BeanPostProcessor 重写 postProcessAfterInitialization 方法
        beanFactory.addBeanPostProcessor(new SpringLifeCycleBeanPostProcessor());
        String[] locations = {"META-INF/dependency-lookup-context.xml", "META-INF/bean-constructor-dependency-injection.xml"};
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions(locations);
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
        SuperUser superUser = beanFactory.getBean("superUser", SuperUser.class);
        System.out.println(superUser);
        UserHolder userHolder = beanFactory.getBean("userHolder", UserHolder.class);
        System.out.println(userHolder);
    }
}

2 源码分析

AbstractAutowireCapableBeanFactory#initializeBean 的最后一个阶段为 初始化后阶段回调,调用了 applyBeanPostProcessorsAfterInitialization 方法

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    // 遍历所有 BeanPostProcessor
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 执行初始化完成后阶段回调方法
        Object current = processor.postProcessAfterInitialization(result, beanName);
        // 如果返回的为 null, 则返回原来的对象
        if (current == null) {
            return result;
        }
        // 否则替换为当前对象
        result = current;
    }
    return result;
}

Chapter 13 Spring Bean 初始化完成阶段

1 概述

方法回调

  • Spring 4.1 +:SmartInitializingSingleton#afterSingletonsInstantiated

在 Spring Bean 的生命周期中,在 ApplicationContext 启动容器的时候,会在 Spring Bean 初始化完成以后才会调用该方法。 特点:

  1. afterSingletonsInstantiated 该方法需要显示调用,在 Spring 环境中,该方法的调用表明 Bean 已经初始化完毕,可以安全使用。
  2. preInstantiateSingletons 是 beanFactory 提供的一个方法,在 Bean 初始化完成以后调用。该方法中会去调用 Bean 的 afterSingletonsInstantiated 方法

什么是未初始化完毕呢? 比如在 BeanPostProcessors 还没执行完毕的时候,就进行了属性的更改或者返回代理对象,导致后续的流程不能正常执行。

2 源码分析

源码位置:AbstractApplicationContext#refresh 在 Spring 容器启动的过程中,会去调用 finishBeanFactoryInitialization 方法,在该方法前,所有 bean 的初始化工作都已经完成。

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
        }
    }
}

3 DefaultListableBeanFactory#preInstantiateSingletons 分析

调用 getBean(beanName); 方法,后面会走 createBean 的流程,也会将 Spring Bean 的生命周期走一遍,这样所有的非延迟加载的 Bean 都会完成初始化,smartSingleton.afterSingletonsInstantiated(); 在执行的时候,Bean 已经初始化完毕了

@Override
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    // 获取 BeanFactory 中的所有 beanNames
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    // 遍历 beanName
    for (String beanName : beanNames) {
        // 根据 beanName 获取 RootBeanDefinition, 该 RootBeanDefinition 已经是触发 Merge 操作后的结果
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 该 RootBeanDefinition 不是抽象类 && 是单例模式 && 不是懒加载
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 是否为工厂 Bean
            if (isFactoryBean(beanName)) {
                // 获取 bean 对象
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                // 如果 bean 是工厂 bean
                if (bean instanceof FactoryBean) {
                    final FactoryBean<?> factory = (FactoryBean<?>) bean;
                    // 是否需要立即初始化
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                        ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            }
            else {
                getBean(beanName);
            }
        }
    }
// Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        // 获取单例对象
        Object singletonInstance = getSingleton(beanName);
        // 如果对象实现了 SmartInitializingSingleton 接口
        if (singletonInstance instanceof SmartInitializingSingleton) {
            // 强制转换为 SmartInitializingSingleton 类型
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                // 触发单例 bean 实例化完成后的回调
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

Chapter 14 Spring Bean 销毁前阶段

1 概述

方法回调

  • DestructionAwareBeanPostProcessor#postProcessBeforeDestruction

2 源码分析

beanFactory#destroyBean

@Override
public void destroyBean(String beanName, Object beanInstance) {
    destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
}
protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
}

调用 DisposableBeanAdapter 的 destroy 方法,接下来重点分析 destroy 方法。

@Override
public void destroy() {
    // 如果 beanPostProcessors 不为空
    if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
        // 找出实现了 DestructionAwareBeanPostProcessor 接口的 bean,并调用 postProcessBeforeDestruction 方法
        for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
            processor.postProcessBeforeDestruction(this.bean, this.beanName);
        }
    }
    
    // 如果是个 DisposableBean 
    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);
            }
        }
    }

    if (this.destroyMethod != null) {
        // 执行用户自定义的销毁方法 (该方法采用反射去调用销毁方法)
        invokeCustomDestroyMethod(this.destroyMethod);
    }
    else if (this.destroyMethodName != null) {
        // 如果配置文件中配置了 destroy 方法
        Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
        if (methodToInvoke != null) {
            invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
        }
    }
}

Chapter 15 Spring Bean 销毁阶段

1 概述

Bean 销毁(Destroy)

  • @PreDestroy 标注方法
  • 实现 DisposableBean 接口的 destroy() 方法
  • 自定义销毁方法