4、Spring创建Bean的生命周期

Spring创建Bean的生命周期详解

AbstractBeanFactory#doGetBean()

在BeanFactory的抽象类AbstractBeanFactory中的doGetBean()方法,是Spring创建Bean的基本方法,在这个方法内,主要做的事有

  1. 检查BeanDefiniton,看类上是否存在@DependsOn注解,如果存在,则需要先创建这些依赖Bean。
  2. 检查Bean的作用域,看是单例还是非单例,单例的话会先从单例池中获取,非单例的会直接进行Bean的创建
  3. 当需要进行Bean的创建时,通过resolveBeanClass(mbd, beanName)对Bean的Class进行加载
  4. 执行**实例化前处理器**
  5. 执行**Bean的实例化**,这里包括推断构造方法
  6. 获取到Bean后,执行**BeanDefinition的后置处理**(postProcessMergedBeanDefinition)
  7. 在处理完BeanDefinition后,执行**实例化后处理器**
  8. Spring自己的**自动注入**
  9. 执行**属性赋值**
  10. 执行**Aware回调**
  11. 执行**初始化前处理器**,包括处理各种注解的情况
  12. 执行**初始化逻辑**
  13. 执行**初始化后处理器**

DependsOn逻辑

  1. 先获取BeanDefinition中的dependsOn数组,这个数组是在解析Class文件的ClassPathBeanDefinitionScanner#doScan()生成BeanDefinition时传入值的
  2. 循环处理数组中的每一个Bean名字
    1. 判断正在创建的Bean和依赖的Bean是否是循环依赖,是的话会抛异常。这里判断的时候,会从dependentBeanMap中取出当前正在创建的Bean被那些Bean依赖的集合,检查这个集合中是否存在依赖的Bean的名字。然后再循环检查集合,看集合中每一个Bean是否被当前依赖的Bean依赖。
    2. 注册依赖关系,包括当前正在创建的Bean依赖那些Bean和正在检查的Bean被当前正在创建的Bean依赖。
    3. 执行getBean(dep)创建依赖Bean
// Guarantee initialization of beans that the current bean depends on.
// 检查dependsOn,看是否需要先初始化某些bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
    for (String dep : dependsOn) {
        // 判断正在创建的Bean与依赖的Bean是否是循环依赖
        if (isDependent(beanName, dep)) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
        }
        // 注册一下依赖关系,注册被依赖的bean被当前创建的bean依赖
        // 注意这里的入参顺序
        registerDependentBean(dep, beanName);
        try {
            // 创建依赖Bean
            getBean(dep);
        }
        catch (NoSuchBeanDefinitionException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
        }
        catch (BeanCreationException ex) {
            if (requiredType != null) {
                // Wrap exception with current bean metadata but only if specifically
                // requested (indicated by required type), not for depends-on cascades.
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Failed to initialize dependency '" + ex.getBeanName() + "' of " +
                                requiredType.getSimpleName() + " bean '" + beanName + "': " +
                                ex.getMessage(), ex);
            }
            throw ex;
        }
    }
}
	private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
		// 已经扫描过的bean集合
		if (alreadySeen != null && alreadySeen.contains(beanName)) {
			return false;
		}
		String canonicalName = canonicalName(beanName);
		// 从dependentBeanMap取出beanName被那些bean依赖
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		//被依赖项为空直接返回false
		if (dependentBeans == null || dependentBeans.isEmpty()) {
			return false;
		}
		// 当前创建的bean被依赖集合中包含当前创建的bean依赖的对象,说明存在循环依赖,返回true抛出异常
		if (dependentBeans.contains(dependentBeanName)) {
			return true;
		}
		if (alreadySeen == null) {
			alreadySeen = new HashSet<>();
		}
		// 如果当前bean的被依赖集合中没有,会继续扫描被依赖的bean是否会被这次检查的dependentBeanName依赖
		// 已经扫描过的bean加入集合
		alreadySeen.add(beanName);
		// 再循环处理被那些依赖的集合
		for (String transitiveDependency : dependentBeans) {
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
				return true;
			}
		}
		return false;
	}

举例

这里对依赖的判断举个例子

User依赖componentIndexDemo,componentIndexDemo依赖order,order依赖user组成循环

代码逻辑内打断点可以看到

第一个进来的创建componentIndexDemo时候,依赖componentIndexDemo的集合还是空的,这里会过,继续创建componentIndexDemo的,同时在外面添加order被componentIndexDemo依赖

当创建order对象时候,会检查order对象和他的依赖名user,此时因为在创建componentIndexDemo时,将order被那些bean依赖已经缓存在了dependentBeanMap中,因此这里dependentBeans中是有值的。在截图的这个断点中,会继续判断componentIndexDemo是否依赖user,当然这里Fran会false。同时会在外面存储order的依赖和被依赖关系

最后创建user的时候先取出被那些依赖,检查被依赖的bean中是否存在componentIndexDemo。

然后会继续循环处理被依赖集合,检查order是否被componentIndexDemo依赖,这里会查出order被componentIndexDemo依赖,就返回true抛出异常

注册依赖关系

注册依赖关系就相对简单一点

  1. 先通过依赖的bean的beanName获取到一个dependentBeans集合,这个集合中都是要@DependsOn这个依赖Bean的,将当前创建的bean添加进去
  2. 将当前创建的bean依赖那些bean添加到dependenciesForBean集合中
/**
 * Register a dependent bean for the given bean,
 * to be destroyed before the given bean is destroyed.
 * @param beanName the name of the bean
 * @param dependentBeanName the name of the dependent bean
 */
public void registerDependentBean(String beanName, String dependentBeanName) {
    String canonicalName = canonicalName(beanName);

    synchronized (this.dependentBeanMap) {
        // 从dependentBeanMap中取出beanName被那些bean依赖的集合
        Set<String> dependentBeans =
                this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
        // 将当前要依赖他的bean名字存入dependentBeanMap
        if (!dependentBeans.add(dependentBeanName)) {
            return;
        }
    }

    //
    synchronized (this.dependenciesForBeanMap) {
        // 添加当前正在创建的Bean,依赖了那些bean加入dependenciesForBeanMap
        Set<String> dependenciesForBean =
                this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
        dependenciesForBean.add(canonicalName);
    }
}

Bean的创建

单例bean或是多例bean在创建时,都会调用createBean()来进行bean的创建及初始化等步骤

createBean(beanName, mbd, args)

在createBean内部,会先进行bean的class加载,然后执行实例化前的方法回调。如果实例化前回调没有返回bean的对象,会调用doCreateBean()方法,让Spring来创建Bean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object @Nullable [] 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.
    // 这里会进行类的加载,将需要实例化的bean的class加载到内存中
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
        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.
        // 这里会执行postProcessBeforeInstantiation()方法,如果有返回对象
        // 会在内部执行初始化后的后置处理器步骤。跳过了实例化,实例化后,依赖注入,初始化前,初始化步骤
        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 + "'");
        }
        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);
    }
}
类加载-resolveBeanClass(mbd, beanName)

前面在分析扫描解析生成BeanDefinition时知道,这个时候是通过ASM解析的Class文件,Spring不会在生成BeanDefinition时就将Class加载到JVM内存中。而现在Spring要创建对象了,那么在创建对象之前需要对要创建Bean的Class进行加载。

protected @Nullable Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
        throws CannotLoadBeanClassException {

    try {
        // 如果beanDefinition中已经保存了beanClass,就用beanDefinition中的
        if (mbd.hasBeanClass()) {
            return mbd.getBeanClass();
        }
        // Spring启动时没有加载过class这里进行加载,这时typesToMatch为null
        Class<?> beanClass = doResolveBeanClass(mbd, typesToMatch);
        if (mbd.hasBeanClass()) {
            mbd.prepareMethodOverrides();
        }
        return beanClass;
    }
    catch (ClassNotFoundException ex) {
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
    }
    catch (LinkageError err) {
        throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }
}

在加载Class类之前,需要确定使用那个classLoader来进行加载,这里Spring会通过getBeanClassLoader()方法来获取classLoader

获取classLoader的逻辑是

  1. 使用当前线程的ClassLoader
  2. 使用ClassUtils的ClassLoader
  3. 使用系统的ClassLoader

确定完ClassLoader后,最终使用Class.forName(name, false, clToUse)加载类。

private @Nullable Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
        throws ClassNotFoundException {
    // 获取beanClassLoader,这里使用的是ClassUtils.getDefaultClassLoader();
    // 使用逻辑就是:
    // 1、使用当前线程的classLoader
    // 2、使用ClassUtils的classLoader
    // 3、使用系统classLoader
    ClassLoader beanClassLoader = getBeanClassLoader();
    ClassLoader dynamicLoader = beanClassLoader;
    boolean freshResolve = false;

    if (!ObjectUtils.isEmpty(typesToMatch)) {
        // Spring启动时,typesToMatch为null,不会走这里
        // When just doing type checks (i.e. not creating an actual instance yet),
        // use the specified temporary class loader (for example, in a weaving scenario).
        ClassLoader tempClassLoader = getTempClassLoader();
        if (tempClassLoader != null) {
            dynamicLoader = tempClassLoader;
            freshResolve = true;
            if (tempClassLoader instanceof DecoratingClassLoader dcl) {
                for (Class<?> typeToMatch : typesToMatch) {
                    dcl.excludeClass(typeToMatch.getName());
                }
            }
        }
    }

    String className = mbd.getBeanClassName();
    if (className != null) {
        Object evaluated = evaluateBeanDefinitionString(className, mbd);
        if (!className.equals(evaluated)) {
            // A dynamically resolved expression, supported as of 4.2...
            if (evaluated instanceof Class<?> clazz) {
                return clazz;
            }
            else if (evaluated instanceof String name) {
                className = name;
                freshResolve = true;
            }
            else {
                throw new IllegalStateException("Invalid class name expression result: " + evaluated);
            }
        }
        if (freshResolve) {
            // When resolving against a temporary class loader, exit early in order
            // to avoid storing the resolved Class in the bean definition.
            if (dynamicLoader != null) {
                try {
                    return dynamicLoader.loadClass(className);
                }
                catch (ClassNotFoundException ex) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
                    }
                }
            }
            return ClassUtils.forName(className, dynamicLoader);
        }
    }

    // Resolve regularly, caching the result in the BeanDefinition...
    // 最终会进这里加载类,里面最终会使用Class.forName(name, false, clToUse)加载类
    return mbd.resolveBeanClass(beanClassLoader);
实例化前处理器-resolveBeforeInstantiation(beanName,mbd)

resolveBeforeInstantiation()方法会执行postProcessorsBeforeInstantiation()方法。该方法允许用户在实例化前将自己创建的对象交给Spring。此时,这个对象不会执行Spring的Bean生命周期中的实例化、实例化后、依赖注入、Aware回调、初始化前、初始化。但会执行初始化后的回调方法。因此,对于对象中的如@PostConstruct``@PreDestroy修饰的方法以及实现了initializingBean接口的afterPropertiesSet()方法均不会执行。

@SuppressWarnings("deprecation")
protected @Nullable Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                // 通过postProcessBeforeInstantiation来获取自己创建的bean
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // 当bean不为null时,执行初始化后的方法,这里跳过了实例化、实例化后、依赖注入、aware回调、初始化前、初始化步骤
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

/**
 * Apply InstantiationAwareBeanPostProcessors to the specified bean definition
 * (by class and name), invoking their {@code postProcessBeforeInstantiation} methods.
 * <p>Any returned object will be used as the bean instead of actually instantiating
 * the target bean. A {@code null} return value from the post-processor will
 * result in the target bean being instantiated.
 * @param beanClass the class of the bean to be instantiated
 * @param beanName the name of the bean
 * @return the bean object to use instead of a default instance of the target bean, or {@code null}
 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
 */
protected @Nullable Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
        if (result != null) {
            // 只要回调返回的不为null,就跳出循环,表示有用户自己创建的Bean来让Spring管理
            return result;
        }
    }
    return null;
}

doCreateBean(beanName, mbdToUse, args)

doCreateBean()方法会真正进行Bean的创建,包括实例化,初始化等步骤

  1. 进行构造方法的推断,然后使用反射实例化对象
  2. 执行postProcessMergedBeanDefinition()方法,其中@Autowired``@Value会在这里查找注入点,并将注入点存储
  3. 执行postProcessAfterInstantiation()方法,当返回false时,会跳过该Bean的创建,Spring中,该方法回调没特殊处理直接返回的true
  4. 执行Spring自己的自动注入
  5. 执行postProcessProperties()方法来处理@Autowired@Value@Resource注解,进行依赖注入
  6. 执行Aware回调
  7. 执行postProcessBeforeInitialization()初始化前方法
  8. 执行invokeInitMethods初始化方法
  9. 执行postProcessAfterInitialization()初始化后方法
推断构造方法,实例化Bean对象
  1. 再次执行resolveBeanClass()方法
  2. 检查beanDefinition中是否存在supplier方法,存在就通过supplier的get()方法获取对象
  3. 检查beanDefinition中是否存有resolvedConstructorOrFactoryMethod
  4. 筛选候选的构造方法数组
  5. 当构造方法数组为null时,表示使用默认的构造函数来实例化对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object @Nullable [] args) {
    // Make sure bean class is actually resolved at this point.
    // 确保bean的class已经加载到jvm了,在走一遍方法
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    if (args == null) {
        // 检查beanDefinition中是否存在supplier方法,存在就使用supplier的get()方法获取对象
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName, mbd);
        }
    }

    if (mbd.getFactoryMethodName() != null) {
        // 有factoryMethodName的,调用FactoryMethod来生成对象
        // 在AppConfig中的@Bean注解修饰的方法都是factoryMethod,在生成bean时候,会调用方法来获取对象
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    // 对于像非单例的对象,在多次生成时,选择过构造方法了,就可以将构造方法存储起来,后续使用时可快速进行构建。
    // 在第一次执行构造方法时,会将选定的构造方法存入mbd.constructorArgumentsResolved;
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    // 筛选候选的构造方法数组
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 当候选构造方法不为null
    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);
}
BeanDefinition后置处理

在Bean的生命周期中,比较重要的是@Autowired``@Value会在这里查找注入点,并将注入点存储

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
        // 获取mergedDefinition对象,执行postProcessMergedBeanDefinition()方法
        processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
    }
}
依赖注入

在整体的依赖注入方法中,

  1. 先执行实例化后处理器,这个Spring中一般都返回true过去了。
  2. 然后执行Spring原有XML中的AUTOWIRE,查找属性对应的值,存入pvs中
  3. 执行postProcessProperties()回调对@Autowired``@Value``@Resource等注解修饰的属性方法进行注入
  4. 执行pvs注入
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;
        }
    }
    //如果创建的对象是Record类型的,那么无法进行属性注入
    if (bw.getWrappedClass().isRecord()) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to a record");
        }
        else {
            // Skip property population phase for records since they are immutable.
            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()
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }

    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    // 这里会对Spring原有的自动注入进行处理,会将查找到的对象和属性名放到pvs中不会直接执行注入方法
    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;
    }
    if (hasInstantiationAwareBeanPostProcessors()) {
        // 这个一般都存在,比如AutowiredAnnotationBeanPostProcessor
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        // 这里使用不同的InstantiationAwareBeanPostProcessor实现类来处理
        // 比较重要的是AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                return;
            }
            pvs = pvsToUse;
        }
    }

    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    if (needsDepCheck) {
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
        // 这里在pvs中有值时,进行注入
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}
初始化

在这个步骤中,Spring会执行一些回调来对bean进行初始化

  1. 执行Aware回调
  2. 执行初始化前处理器
  3. 执行invokeInitMethods来初始化Bean
  4. 执行初始化后处理器
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 执行部分aware回调
    invokeAwareMethods(beanName, bean);

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 执行BeanPostProcessorsBeforeInitialization()方法回调,处理@PostConstruct
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 如果当前的Bean是InitializingBean类型的,执行afterPropertiesSet()
        // 如果BeanDefinition中配置了init-method,执行init-method
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 执行BeanPostProcessorsAfterInitialization()方法
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
Aware回调

主要进行beanNameAware``beanClassLoaderAware``beanFactoryAware三种回调

private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        // 当前Bean是aware的一个实现
        if (bean instanceof BeanNameAware beanNameAware) {
            // 执行beanNameAware回调
            beanNameAware.setBeanName(beanName);
        }

        if (bean instanceof BeanClassLoaderAware beanClassLoaderAware) {
            // 执行beanClassLoaderAware回调
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                beanClassLoaderAware.setBeanClassLoader(bcl);
            }
        }

        if (bean instanceof BeanFactoryAware beanFactoryAware) {
            //  执行beanFactoryAware回调
            beanFactoryAware.setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}
初始化前处理器
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}
@PostConstruct的处理

在这需要先说明一下,在处理@PostConstruct@PreDestroy注解的主要是InitDestroyAnnotationBeanPostProcessor类,这个类有一个子类CommonAnnotationBeanPostProcessor在它的构造方法中,会将要处理的初始化注解和销毁时的注解存起来,在进行初始化前处理的时候,会检查Bean中是否有方法带有这些注解,然后将这些方法缓存起来,等待对应的时候执行。

以下是CommonAnnotationBeanPostProcessor的构造方法

public CommonAnnotationBeanPostProcessor() {
    setOrder(Ordered.LOWEST_PRECEDENCE - 3);

    // Jakarta EE 9 set of annotations in jakarta.annotation package
    //添加要处理的init注解和destroy注解类型
    addInitAnnotationType(loadAnnotationType("jakarta.annotation.PostConstruct"));
    addDestroyAnnotationType(loadAnnotationType("jakarta.annotation.PreDestroy"));

    // java.naming module present on JDK 9+?
    if (jndiPresent) {
        this.jndiFactory = new SimpleJndiBeanFactory();
    }
}

postProcessMergedBeanDefinition时,InitDestroyAnnotationBeanPostProcessor会处理查找bean的LifecycleMetadata然后对查找到的Init和Destroy方法进行校验。

创建LifecycleMetadata的主要方法是buildLifecycleMetadata(final Class<?> beanClass)方法

private LifecycleMetadata buildLifecycleMetadata(final Class<?> beanClass) {
    // 如果当前bean名称是java开头的原始类,比如String,或者是Ordered类就返回空的
    if (!AnnotationUtils.isCandidateClass(beanClass, this.initAnnotationTypes) &&
            !AnnotationUtils.isCandidateClass(beanClass, this.destroyAnnotationTypes)) {
        return this.emptyLifecycleMetadata;
    }

    List<LifecycleMethod> initMethods = new ArrayList<>();
    List<LifecycleMethod> destroyMethods = new ArrayList<>();
    Class<?> currentClass = beanClass;

    do {
        //循环处理当前Bean和Bean的父类
        final List<LifecycleMethod> currInitMethods = new ArrayList<>();
        final List<LifecycleMethod> currDestroyMethods = new ArrayList<>();

        ReflectionUtils.doWithLocalMethods(currentClass, method -> {
            for (Class<? extends Annotation> initAnnotationType : this.initAnnotationTypes) {
                //doWithLocalMethods中会循环处理每一个方法,这里判断方法上是否存在initAnnotationTypes中的注解,一般只有一个PostConstruct
                if (initAnnotationType != null && method.isAnnotationPresent(initAnnotationType)) {
                    //方法封装为LifecycleMethod存入currInitMethods中
                    currInitMethods.add(new LifecycleMethod(method, beanClass));
                    if (logger.isTraceEnabled()) {
                        logger.trace("Found init method on class [" + beanClass.getName() + "]: " + method);
                    }
                }
            }
            for (Class<? extends Annotation> destroyAnnotationType : this.destroyAnnotationTypes) {
                //方法是否存在destroyAnnotationTypes中的注解,一般只有一个PreDestroy
                if (destroyAnnotationType != null && method.isAnnotationPresent(destroyAnnotationType)) {
                    // 方法封装为LifecycleMethod存入currDestroyMethods中
                    currDestroyMethods.add(new LifecycleMethod(method, beanClass));
                    if (logger.isTraceEnabled()) {
                        logger.trace("Found destroy method on class [" + beanClass.getName() + "]: " + method);
                    }
                }
            }
        });
        // 将两加入队列头部
        initMethods.addAll(0, currInitMethods);
        destroyMethods.addAll(currDestroyMethods);
        // 将类换为父类,再次执行,知道父类为Object时结束
        currentClass = currentClass.getSuperclass();
    }
    while (currentClass != null && currentClass != Object.class);
    // 返回LifecycleMetadata,里面包含了initMethods和destroyMethods
    return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
            new LifecycleMetadata(beanClass, initMethods, destroyMethods));
}

校验LifecycleMetadata方法,这里会将这些方法存入externallyManagedInitMethods中,请记住这个数组,下面要用到

public void checkInitDestroyMethods(RootBeanDefinition beanDefinition) {
    // 初始化一个list
    Set<LifecycleMethod> checkedInitMethods = CollectionUtils.newLinkedHashSet(this.initMethods.size());

    for (LifecycleMethod lifecycleMethod : this.initMethods) {
        // 循环处理initMethods中每一个methods,这里获取方法的全限定名
        String methodIdentifier = lifecycleMethod.getIdentifier();
        if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
            // 这个方法不在externallyManagedInitMethods数组中,则加入checkedInitMethods中
            beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
            checkedInitMethods.add(lifecycleMethod);
            if (logger.isTraceEnabled()) {
                logger.trace("Registered init method on class [" + this.beanClass.getName() + "]: " + methodIdentifier);
            }
        }
    }
    //相同的,循环处理销毁前方法
    Set<LifecycleMethod> checkedDestroyMethods = CollectionUtils.newLinkedHashSet(this.destroyMethods.size());
    for (LifecycleMethod lifecycleMethod : this.destroyMethods) {
        String methodIdentifier = lifecycleMethod.getIdentifier();
        if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
            beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
            checkedDestroyMethods.add(lifecycleMethod);
            if (logger.isTraceEnabled()) {
                logger.trace("Registered destroy method on class [" + this.beanClass.getName() + "]: " + methodIdentifier);
            }
        }
    }
    this.checkedInitMethods = checkedInitMethods;
    this.checkedDestroyMethods = checkedDestroyMethods;
}

在执行是,就是从缓存中获取到类的LifecycleMetadata,然后取出初始化的initMethods或者checkedInitMethods集合,然后循环遍历这个集合,利用反射执行集合中的方法

public void invokeInitMethods(Object target, String beanName) throws Throwable {
    // 获取检查过的initMethods
    Collection<LifecycleMethod> checkedInitMethods = this.checkedInitMethods;
    // 有检查过的initMethods用检查过的,没有检查过的用initMethods中的
    Collection<LifecycleMethod> initMethodsToIterate =
            (checkedInitMethods != null ? checkedInitMethods : this.initMethods);
    if (!initMethodsToIterate.isEmpty()) {
        //循环处理执行初始化方法
        for (LifecycleMethod lifecycleMethod : initMethodsToIterate) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking init method on bean '" + beanName + "': " + lifecycleMethod.getMethod());
            }
            // 执行方法
            lifecycleMethod.invoke(target);
        }
    }
}
初始化

在初始化时,会判断当前的bean是不是InitializingBean,当是InitializingBean是,会判断afterPropertiesSet方法是否存在于externallyManagedInitMethods中,如果存在,也不执行。当不存在时,会通过强转执行afterPropertiesSet方法

同时初始化也会执行在自定义BeanDefinition或者xml中配置init-method属性的话,Spring在这步也会执行。

首先获取配置的init-methods方法数组,然后循环每一个名字,判断

  1. 当类是InitializingBean,且afterPropertiesSet在init-methods中时跳过不执行
  2. 这个名字在externallyManagedInitMethods中存在,也跳过不执行

当以上两个都不满足时,会通过反射的方式调用bean的init-method方法

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {

    // 是不是InitializingBean
    boolean isInitializingBean = (bean instanceof InitializingBean);
    // 是InitializingBean,且要么mbd为null,要么afterPropertiesSet方法不存在于externallyManagedInitMethods中
    if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isTraceEnabled()) {
            logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        // 执行afterPropertiesSet()方法
        ((InitializingBean) bean).afterPropertiesSet();
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        // 在生成的bean不是NullBean
        // 获取配置的init-methods方法数组
        String[] initMethodNames = mbd.getInitMethodNames();
        if (initMethodNames != null) {
            for (String initMethodName : initMethodNames) {
                // 循环每一个名字,判断
                // 1.当类是InitializingBean,且afterPropertiesSet在init-methods中时跳过不执行
                // 2.这个名字在externallyManagedInitMethods中存在,也跳过不执行
                if (StringUtils.hasLength(initMethodName) &&
                        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                        !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
                    // 这个方法里最后通过反射执行initMethodName的方法
                    invokeCustomInitMethod(beanName, bean, mbd, initMethodName);
                }
            }
        }
    }
}
初始化后处理器

在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象

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

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 处理BeanPostProcessor.postProcessAfterInitialization()初始化后方法
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值