Spring Bean生命周期——从源码角度详解Spring Bean的生命周期(下)-CSDN博客

文章目录

写在前面

书接上文
Spring Bean生命周期------从源码角度详解Spring Bean的生命周期(上)

Spring Bean生命周期------从源码角度详解Spring Bean的生命周期(下)

七、Spring Bean 属性赋值前阶段

首先我们明确一个概念,BeanDefinition中保存着Bean属性值的原信息-propertyValues:

java 复制代码
@Nullable
private MutablePropertyValues propertyValues;

当然,如果使用构造器的话,就会使用constructorArgumentValues存储构造器的参数信息:

java 复制代码
@Nullable
private ConstructorArgumentValues constructorArgumentValues;

Bean属性赋值之前,是有一个回调的,在Spring 1.2 - 5.0版本中,使用的是InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法;在Spring 5.1之后的版本中,使用的是InstantiationAwareBeanPostProcessor的postProcessProperties方法。

InstantiationAwareBeanPostProcessor接口我们在上面已经介绍过,它里面有着Bean实例化前和实例化后的回调方法。

我们一起来看一下InstantiationAwareBeanPostProcessor接口中的这两个方法:

java 复制代码
/**
 * spring5.1之后统一使用该方法作为属性赋值前的回调
 * PropertyValues pvs参数为将要赋值的属性值
 */
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
		throws BeansException {

	return null;
}

/**
 * 该方法从5.1开始弃用,5.1之后使用postProcessProperties(PropertyValues, Object, String)
 */
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
		PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

	return pvs;
}

1、代码实例

java 复制代码
class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {
        // 对 "userHolder" Bean 进行拦截
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && UserHolder.class.equals(bean.getClass())) {
            // 假设 <property name="number" value="1" /> 配置的话,那么在 PropertyValues pvs 就包含一个 PropertyValue(number=1)

            final MutablePropertyValues propertyValues;

            if (pvs instanceof MutablePropertyValues) {
                propertyValues = (MutablePropertyValues) pvs;
            } else {
                propertyValues = new MutablePropertyValues();
            }

            // 等价于 <property name="number" value="1" />
            propertyValues.addPropertyValue("number", "1");
            // 原始配置 <property name="description" value="The user holder" />

            // 如果存在 "description" 属性配置的话
            if (propertyValues.contains("description")) {
                // PropertyValue value 是不可变的 (final修饰)
//                    PropertyValue propertyValue = propertyValues.getPropertyValue("description");
                propertyValues.removePropertyValue("description");
                propertyValues.addPropertyValue("description", "The user holder V2");
            }

            return propertyValues;
        }
        return null;
    }

}

然后需要将MyInstantiationAwareBeanPostProcessor 注册到Spring IOC容器中,同上 (Spring Bean实例化前阶段)。

2、源码分析

在第六节,Spring Bean实例化后阶段的源码分析中,我们找到了AbstractAutowireCapableBeanFactory的populateBean方法,我们接下来继续分析该方法:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	if (bw == null) {
		if (mbd.hasPropertyValues()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		}
		else {
			// Skip property population phase for null instance.
			return;
		}
	}

	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
	// state of the bean before properties are set. This can be used, for example,
	// to support styles of field injection.
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 返回false的话,直接return,后面的逻辑全不会执行
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { 
					return;
				}
			}
		}
	}

	// postProcessAfterInstantiation没有返回false的,会执行下面的逻辑
	
	// // 默认的属性配置,来自配置文件或者自定义
	PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); 

	int resolvedAutowireMode = mbd.getResolvedAutowireMode();// 自动绑定相关
	if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
		// Add property values based on autowire by name if applicable.
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}
		// Add property values based on autowire by type if applicable.
		if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}
		pvs = newPvs;
	}

	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;
				// 执行InstantiationAwareBeanPostProcessor的postProcessProperties方法
				PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) { // 如果返回空的话,会执行被废弃的postProcessPropertyValues方法
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) { // 如果postProcessPropertyValues方法仍然返回null,就直接返回
						return;
					}
				}
				// 如果返回的不是null,就将PropertyValues应用
				pvs = pvsToUse;
			}
		}
	}
	if (needsDepCheck) {
		if (filteredPds == null) {
			filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		}
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}

	if (pvs != null) { // 运用这个属性值,到我的BeanWrapper里面去
		applyPropertyValues(beanName, mbd, bw, pvs);
	}
}

3、总结分析

总结InstantiationAwareBeanPostProcessor方法:

  • postProcessBeforeInstantiation()在bean实例化前回调,返回实例则不对bean实例化,返回null则进行spring bean实例化(doCreateBean);
  • postProcessAfterInstantiation()在bean实例化后在填充bean属性之前回调,返回true则进行下一步的属性填充,返回false则不进行属性填充;
  • postProcessProperties在属性赋值前的回调在applyPropertyValues之前操作可以对属性添加或修改等操作最后在通过applyPropertyValues应用bean对应的wapper对象

但是这里要注意一点,如果是使用@Bean的方式产生的Bean,是没有PropertValue的,因为 @Bean 本来就是 Java Config。虽然没有PropertValue,但是仍然可以使用postProcessProperties方法来拦截,只是获取不到PropertValue。

八、Spring Bean Aware接口回调阶段

Spring Aware 接口有很多,我们称为Spring的回调接口(下面的列表是回调的顺序):

  • BeanNameAware:bean名称回调
  • BeanClassLoaderAware:bean对应的classLoader回调
  • BeanFactoryAware:BeanFactory回调
  • EnvironmentAware:Environment环境回调
  • EmbeddedValueResolverAware:EmbeddedValueResolver回调(实际上存在的是StringValueResolver)
  • ResourceLoaderAware:ResourceLoader回调
  • ApplicationEventPublisherAware:ApplicationEventPublisher回调
  • MessageSourceAware:MessageSource回调用于Spring国际化
  • ApplicationContextAware:ApplicationContext回调注入ApplicationContext

1、BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

代码实例

bean实现BeanNameAware, BeanClassLoaderAware, BeanFactoryAware接口,即可获取beanName、ClassLoader、BeanFactory ,这三个是按照顺序获取的,我们可以在bean中定义一个属性来保存它。

java 复制代码
public class UserHolder implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {

    private ClassLoader classLoader;

    private BeanFactory beanFactory;

    private String beanName;

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

源码分析

在第六节,Bean实例化后阶段我们分析到,AbstractAutowireCapableBeanFactory的doCreateBean方法中,调用了populateBean方法属性值的填入之后,调用了initializeBean方法,我们回顾一下:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
		throws BeanCreationException {

	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		// 上面分析的,Spring自身实例化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 {
				// 这里有一个MergedBeanDefinitionPostProcessor的回调,执行postProcessMergedBeanDefinition方法
				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);
		// Bean的初始化(关键方法)
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}

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

我们继续看initializeBean方法:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean); // 执行Aware回调
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean); // 执行Aware回调
	}

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

我们可以找到,在AbstractAutowireCapableBeanFactory的invokeAwareMethods方法中,设置了这三个Aware接口的回调方法:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
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);
		}
	}
}

总结分析

我们可以看出,这几个Aware回调接口是在initializeBean方法中回调的,也就是说属于Bean的初始化阶段的回调。

而BeanNameAware、BeanClassLoaderAware、BeanFactoryAware这三个回调接口,是写在一起的。

2、剩下的几个Aware

实际上,除了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware这三个回调接口属于Bean的生命周期接口,剩下的EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware是属于ApplicationContext生命周期里面的。

源码分析

实际上,在Spring IOC容器启动的过程中,会执行AbstractApplicationContext类中的prepareBeanFactory方法。

关于Spring IOC容器启动过程请移步:
spring系列-注解驱动原理及源码-spring容器创建流程

java 复制代码
// org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	beanFactory.setBeanClassLoader(getClassLoader());
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// Configure the bean factory with context callbacks.
	// 关键!增加了ApplicationContextAwareProcessor
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
	beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

	// BeanFactory interface not registered as resolvable type in a plain factory.
	// MessageSource registered (and found for autowiring) as a bean.
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	// Register early post-processor for detecting inner beans as ApplicationListeners.
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		// Set a temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}

	// Register default environment beans.
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}

我们可以看到,其中执行了beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 注册了一个ApplicationContextAwareProcessor。

而ApplicationContextAwareProcessor接口的postProcessBeforeInitialization方法中,我们可以很清晰的看到,它注册了剩下的几个Aware。

java 复制代码
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
	AccessControlContext acc = null;

	if (System.getSecurityManager() != null &&
			(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
					bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
					bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
		acc = this.applicationContext.getBeanFactory().getAccessControlContext();
	}

	if (acc != null) {
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			@Override
			public Object run() {
				invokeAwareInterfaces(bean);
				return null;
			}
		}, acc);
	}
	else {
		invokeAwareInterfaces(bean);
	}

	return bean;
}

private void invokeAwareInterfaces(Object bean) {
	if (bean instanceof Aware) {
		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);
		}
	}
}

总结分析

剩下的几个Arare的回调,实际上是只有与ApplicationContext打交道时才会进行回调,而回调的方法正是ApplicationContextAwareProcessor的postProcessBeforeInitialization方法,该方法是BeanPostProcessor中的方法,正是下面我们要继续接触的,属于Bean初始化的生命周期。

与ApplicationContext打交道也就意味着需要启动Spring IOC容器,下面简单一个实例:

java 复制代码
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
String[] locations = {"META-INF/bean.xml"};
applicationContext.setConfigLocations(locations);
// 启动应用上下文
applicationContext.refresh();

User user = applicationContext.getBean("user", User.class);
System.out.println(user);

// 关闭应用上下文
applicationContext.close();

九、Spring Bean 初始化阶段

1、Bean初始化前阶段

通过我们上面的学习,知道了Bean初始化前阶段已经完成了Bean的实例化、Bean属性赋值、Bean Aware接口的回调。

Bean初始化前也有一个方法回调,就是BeanPostProcessor接口的postProcessBeforeInitialization方法。

代码实例

java 复制代码
class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && UserHolder.class.equals(bean.getClass())) {
            UserHolder userHolder = (UserHolder) bean;
            // UserHolder description = "The user holder V2"
            userHolder.setDescription("The user holder V3");
        }
        return bean;
    }

}

然后将MyInstantiationAwareBeanPostProcessor 注入到IOC容器中。

源码分析

实际上,上面我们使用的InstantiationAwareBeanPostProcessor接口,是继承了BeanPostProcessor的,所以我们也可以直接实现InstantiationAwareBeanPostProcessor接口,实现postProcessBeforeInitialization即可。

java 复制代码
/**
 * org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
 * 如果该方法不做任何的修改,直接返回原bean即可
 * 如果想对bean做任何处理,直接在方法中处理即可
 */
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

上面第八节我们分析到,在AbstractAutowireCapableBeanFactory的initializeBean方法中,执行了Aware回调,接下来我们继续分析:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean); // 执行Aware回调
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean); // 执行Aware回调
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		// 逐一迭代BeanPostProcessor,执行postProcessBeforeInitialization
		// 返回值有可能是原始的对象,可能是代理对象,可能是被处理过的原始对象
		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;
}

获取所有的BeanPostProcessor 逐一迭代,执行postProcessBeforeInitialization:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
@Override
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; // 返回了不为null,使用了处理过的bean,可以用于bean的封装,做一下代理
	}
	return result;
}

BeanPostProcessor是如何注册到IOC中的

关于Spring IOC容器启动过程请移步:
spring系列-注解驱动原理及源码-spring容器创建流程

在IOC容器启动的过程中,会执行registerBeanPostProcessors(beanFactory);方法,就是注册所有的BeanPostProcessor:

java 复制代码
// org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

// org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// Register BeanPostProcessorChecker that logs an info message when
	// a bean is created during BeanPostProcessor instantiation, i.e. when
	// a bean is not eligible for getting processed by all BeanPostProcessors.
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// Separate between BeanPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	List<String> orderedPostProcessorNames = new ArrayList<>();
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// First, register the BeanPostProcessors that implement PriorityOrdered.
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// Finally, re-register all internal BeanPostProcessors.
	sortPostProcessors(internalPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	// Re-register post-processor for detecting inner beans as ApplicationListeners,
	// moving it to the end of the processor chain (for picking up proxies etc).
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

BeanPostProcessor注册有两种方式:

1.ConfigurableBeanFactory. addBeanPostProcessor()手动添加。

手动添加的BeanPostProcessor根据添加的顺序作为执行的顺序;

applicationContext.addBeanFactoryPostProcessor(beanFactory -> {

beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor() );

beanFactory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor() );

});

2.通过ApplicationContext自动检测:beanFactory.getBeanNamesForType(BeanPostProcessor.class)

PostProcessorRegistrationDelegate#registerBeanPostProcessors(ConfigurableListableBeanFactory,AbstractApplicationContext)

执行顺序:

priorityOrderedPostProcessors > orderedPostProcessors > nonOrderedPostProcessors(比如MyInstantiationAwareBeanPostProcessor) > internalPostProcessors(比如CommonAnnotationBeanPostProcessor)

手动添加的BeanPostProcessor总是先于自动检测的。

总结分析

我们上面第八节提到的ApplicationContextAwareProcessor的postProcessBeforeInitialization方法,该方法是BeanPostProcessor中的方法回调,也就是本小节分析的Bean初始化前阶段的回调。

InstantiationAwareBeanPostProcessor接口继承了BeanPostProcessor接口,所以通过实现InstantiationAwareBeanPostProcessor接口就可以重写以下两个初始化拦截方法。

● postProcessBeforeInitialization初始化前拦截操作

● postProcessAfterInitialization初始化后拦截操作

♻️执行时机:

在AbstractAutowireCapableBeanFactory的initializeBean初始化方法中:

①先是执行了invokeAwareMethods方法来对实现BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三个接口的bean进行set属性设置。

②然后,会调用applyBeanPostProcessorsBeforeInitialization方法去遍历执行所有的BeanPostProcessor的postProcessBeforeInitialization方法。

③接着是invokeInitMethods方法。

④最后,会调用applyBeanPostProcessorsAfterInitialization方法去遍历执行所有的BeanPostProcessor的postProcessAfterInitialization方法。

2、Bean 初始化阶段

Bean的初始化有三种方法:

  • @PostConstruct 标注方法:这种方式需要依赖注解驱动
  • 实现 InitializingBean 接口的 afterPropertiesSet() 方法
  • 自定义初始化方法

代码实例

java 复制代码
public class UserHolder implements InitializingBean {

    private Integer number;

    private String description;

    /**
     * 依赖于注解驱动
     */
    @PostConstruct
    public void initPostConstruct() {
        // 来自postProcessBeforeInitialization 的V3 -> initPostConstruct V4
        this.description = "The user holder V4";
        System.out.println("initPostConstruct() = " + description);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // initPostConstruct V4 -> afterPropertiesSet V5
        this.description = "The user holder V5";
        System.out.println("afterPropertiesSet() = " + description);
    }

    /**
     * 自定义初始化方法
     * 需要在@Bean(initMethod = "init") 或者xml中定义Bean的init-method="init"
     */
    public void init() {
        // initPostConstruct V5 -> afterPropertiesSet V6
        this.description = "The user holder V6";
        System.out.println("init() = " + description);
    }
    
}

源码分析

上面Bean初始化前阶段我们分析了AbstractAutowireCapableBeanFactory的initializeBean,接下来我们继续分析:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean); // 执行Aware回调
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean); // 执行Aware回调
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		// 逐一迭代BeanPostProcessor,执行postProcessBeforeInitialization
		// 返回值有可能是原始的对象,可能是代理对象,可能是被处理过的原始对象
		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;
}
java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
		throws Throwable {

	boolean isInitializingBean = (bean instanceof InitializingBean);
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
					((InitializingBean) bean).afterPropertiesSet();
					return null;
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else { // 执行afterPropertiesSet方法
			((InitializingBean) bean).afterPropertiesSet();
		}
	}

	if (mbd != null && bean.getClass() != NullBean.class) {
		String initMethodName = mbd.getInitMethodName();
		if (StringUtils.hasLength(initMethodName) &&
				!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
			// 通过反射执行自定义initMethods
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

@PostConstruct是怎么处理的

实际上,在CommonAnnotationBeanPostProcessor中,对@PostConstruct进行了处理。

java 复制代码
// org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#CommonAnnotationBeanPostProcessor
public CommonAnnotationBeanPostProcessor() {
	setOrder(Ordered.LOWEST_PRECEDENCE - 3);
	setInitAnnotationType(PostConstruct.class);
	setDestroyAnnotationType(PreDestroy.class);
	ignoreResourceType("javax.xml.ws.WebServiceContext");
}

// org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#setInitAnnotationType
public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
	this.initAnnotationType = initAnnotationType;
}

通过setInitAnnotationType 将@PostConstruct和@PreDestroy放到initAnnotationType中:

java 复制代码
@Nullable
private Class<? extends Annotation> initAnnotationType;

在InitDestroyAnnotationBeanPostProcessor中对initAnnotationType进行了判断,最终将方法塞入到initMethods的一个List中,最终用于执行初始化方法。

java 复制代码
// org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#buildLifecycleMetadata
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));
}

实际上,CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,在InitDestroyAnnotationBeanPostProcessor中有postProcessBeforeInitialization方法,其实 @PostConstruct就是在此处进行处理的:

java 复制代码
// org.springframework.beans.factory.annotation.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;
}

// org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata#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());
			}
			element.invoke(target);
		}
	}
}

所以说,@PostConstruct执行的最早。

总结分析

@PostConstruct(非必须)也会在初始化前阶段执行,因为它跟@PreDestroy注解一样被CommonAnnotationBeanPostProcessor管理和执行,CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,这个继承类实现了BeanPostProcessor接口,在初始化前阶段InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization方法会被调用,这其中就执行了metadata.invokeInitMethods(bean, beanName);这个方法,也就是注解了PostConstruct的方法。

afterPropertiesSet方法和自定义方法,在初始化方法的invokeInitMethods方法中执行。

3、Bean 初始化后阶段

关键方法:BeanPostProcessor的postProcessAfterInitialization方法。

与Bean初始化前阶段用法相同。

代码实例

java 复制代码
class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && UserHolder.class.equals(bean.getClass())) {
            UserHolder userHolder = (UserHolder) bean;
            // init() = The user holder V6
            // UserHolder description = "The user holder V6"
            userHolder.setDescription("The user holder V7");
        }
        return bean;
    }
}

源码分析

我们继续回到AbstractAutowireCapableBeanFactory的initializeBean方法:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean); // 执行Aware回调
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean); // 执行Aware回调
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		// 逐一迭代BeanPostProcessor,执行postProcessBeforeInitialization
		// 返回值有可能是原始的对象,可能是代理对象,可能是被处理过的原始对象
		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()) {
		// 逐一迭代BeanPostProcessor,执行postProcessAfterInitialization
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

下面的方法与Bean初始化前方法执行逻辑相同,也可以处理bean。

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

4、总结分析

AbstractAutowireCapableBeanFactory#initializeBean初始化过程:

  • 1.invokeAwareMethods(初始化前,回调Bean实现BeanNameAware|BeanClassLoaderAware|BeanFactoryAware接口的方法)
  • 2.applyBeanPostProcessorsBeforeInitialization(初始化前,回调BeanPostProcessor.postProcessBeforeInitialization方法,包括ApplicationContextAwareProcessor处理
    EnvironmentAware|ApplicationContextAware等接口实现、CommonAnnotationBeanPostProcessor处理@PostConstruct注解方法)
  • 3.invokeInitMethods(初始化中,先后处理initializingBean.afterPropertiesSet接口方法实现、自定义init-method初始化方法)
  • 4.applyBeanPostProcessorsAfterInitialization(完成初始化后,回调BeanPostProcessor.postProcessAfterInitialization方法,例如ApplicationListener Bean初始化之后,ApplicationListenerDetector在此阶段将其添加到applicationContext)

十、Spring Bean 初始化完成阶段

Spring 4.1 版本之后:SmartInitializingSingleton的afterSingletonsInstantiated方法回调。

如果Spring低于4.1版本的话,这个接口回调是不存在的。

1、代码实例

java 复制代码
public class UserHolder implements SmartInitializingSingleton {

    private Integer number;

    private String description;

    @Override
    public void afterSingletonsInstantiated() {
        // postProcessAfterInitialization V7 -> afterSingletonsInstantiated V8
        this.description = "The user holder V8";
        System.out.println("afterSingletonsInstantiated() = " + description);
    }
}

2、源码分析

我们看一下SmartInitializingSingleton接口:

java 复制代码
public interface SmartInitializingSingleton {
	
	/* 
	 * 在单例预实例化阶段结束时调用,并保证已经创建了所有常规单例bean。
	 * 该方法没有任何的参数与返回值,但是可以使用this关键字来获取当前类中的参数,也可以设置参数
	 */
	void afterSingletonsInstantiated();
}

SmartInitializingSingleton 的afterSingletonsInstantiated方法,是在下面的方法中进行回调的,DefaultListableBeanFactory的preInstantiateSingletons方法,遍历所有的bean,然后执行afterSingletonsInstantiated方法:

java 复制代码
// org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
@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.
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// Trigger initialization of all non-lazy singleton beans...
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			if (isFactoryBean(beanName)) {
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				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);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else { // 遍历bean,执行afterSingletonsInstantiated
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}

实际上,DefaultListableBeanFactory的preInstantiateSingletons方法是在Spring IOC启动过程中,执行的finishBeanFactoryInitialization(beanFactory);方法中执行的:

java 复制代码
// org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// Initialize conversion service for this context.
	if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
		beanFactory.setConversionService(
				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
	}

	// Register a default embedded value resolver if no bean post-processor
	// (such as a PropertyPlaceholderConfigurer bean) registered any before:
	// at this point, primarily for resolution in annotation attribute values.
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}

	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// Stop using the temporary ClassLoader for type matching.
	beanFactory.setTempClassLoader(null);

	// Allow for caching all bean definition metadata, not expecting further changes.
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons(); // 显式调用preInstantiateSingletons方法
}

3、总结分析

抛开SmartInitializingSingleton 的afterSingletonsInstantiated方法,DefaultListableBeanFactory的preInstantiateSingletons方法中,遍历所有的beanName,逐一的进行getBean,相当于把所有的bean进行初始化并注册到BeanFactory中进行缓存。

bean初始化完成之后才逐一回调bean的afterSingletonsInstantiated方法(也就是说当所有的BeanDefinition已经变成Bean之后,才会逐一回调afterSingletonsInstantiated方法,所有的Bean都完成了初始化)。

ApplicationContext在refresh的操作里等beanFactory的一系列操作,messageSource,注册listener等操作都完毕之后通过finishBeanFactoryInitialization开始实例化所有非懒加载的单例bean,具体是在finishBeanFactoryInitialization调用beanFactory#preInstantiateSingletons进行的,preInstantiateSingletons里面就是通过beanDefinitionNames循环调用getBean来实例化bean的,这里有个细节,beanDefinitionNames是拷贝到一个副本中,循环副本,使得还能注册新的beanDefinition.

getBean的操作就是最终得到一个完整的状态的bean。 然后所有的非延迟单例都加载完毕之后,再重新循环副本,判断bean是否是SmartInitializingSingleton,如果是的话执行SmartInitializingSingleton#afterSingletonsInstantiated。这保证执行afterSingletonsInstantiated的时候的bean一定是完整的。

十一、Spring Bean 销毁前阶段

主要方法回调:DestructionAwareBeanPostProcessor接口的postProcessBeforeDestruction方法。

1、代码实例

需要触发Bean的销毁才能执行该逻辑。

java 复制代码
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        if (ObjectUtils.nullSafeEquals("userHolder", beanName) && UserHolder.class.equals(bean.getClass())) {
            UserHolder userHolder = (UserHolder) bean;
            // afterSingletonsInstantiated() = The user holder V8
            // UserHolder description = "The user holder V8"
            userHolder.setDescription("The user holder V9");
            System.out.println("postProcessBeforeDestruction() : " + userHolder.getDescription());
        }
    }
}

2、源码分析

我们来看一下DestructionAwareBeanPostProcessor接口的postProcessBeforeDestruction方法:

java 复制代码
// org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

Bean的销毁实际发生在DefaultListableBeanFactory的父类AbstractAutowireCapableBeanFactory中的destroyBean方法:

java 复制代码
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
@Override
public void destroyBean(Object existingBean) {
	new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
}

最终都会调用DisposableBeanAdapter的destroy方法:

java 复制代码
// org.springframework.beans.factory.support.DisposableBeanAdapter#destroy
@Override
public void destroy() {
	if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
		// 逐一迭代DestructionAwareBeanPostProcessor,执行postProcessBeforeDestruction方法
		for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
			processor.postProcessBeforeDestruction(this.bean, this.beanName);
		}
	}

	if (this.invokeDisposableBean) {
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
		}
		try {
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
					((DisposableBean) this.bean).destroy(); // 最终调用bean的destroy方法(需要实现DisposableBean接口)
					return null;
				}, this.acc);
			}
			else {
				((DisposableBean) this.bean).destroy(); // 最终调用bean的destroy方法(需要实现DisposableBean接口)
			}
		}
		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) {
		Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
		if (methodToInvoke != null) {
			invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
		}
	}
}

3、总结分析

我们所说的Bean的销毁,只是在IOC容器中进行销毁,并不意味着立马会被GC掉。

Bean的销毁一般有两种方式触发,一种是调用BeanFactory的destroySingletons方法,另一种是spring应用上下文关闭时。

十二、Spring Bean 销毁阶段

Spring Bean销毁有三种方式:

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

1、代码实例

java 复制代码
public class UserHolder implements DisposableBean {

    private Integer number;

    private String description;

	// 需要注解驱动
    @PreDestroy
    public void preDestroy() {
        // postProcessBeforeDestruction : The user holder V9
        this.description = "The user holder V10";
        System.out.println("preDestroy() = " + description);
    }

    @Override
    public void destroy() throws Exception {
        // preDestroy : The user holder V10
        this.description = "The user holder V11";
        System.out.println("destroy() = " + description);
    }

	/*
	 * 自定义销毁方法,需要@Bean(destroy = "doDestroy") 或者用xml:<bean destroy-method="doDestroy" ... /> 或者用Java API方式
	 */
    public void doDestroy() {
        // destroy : The user holder V11
        this.description = "The user holder V12";
        System.out.println("doDestroy() = " + description);
    }
}

2、源码分析

实际上我们在第十一节中已经分析过了,DisposableBeanAdapter的destroy方法最终会执行postProcessBeforeDestruction、实现DisposableBean接口的destroy方法、自定义destroy方法。

java 复制代码
// org.springframework.beans.factory.support.DisposableBeanAdapter#destroy
@Override
public void destroy() {
	if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
		// 逐一迭代DestructionAwareBeanPostProcessor,执行postProcessBeforeDestruction方法
		for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
			processor.postProcessBeforeDestruction(this.bean, this.beanName);
		}
	}

	if (this.invokeDisposableBean) {
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
		}
		try {
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
					((DisposableBean) this.bean).destroy(); // 最终调用bean的destroy方法(需要实现DisposableBean接口)
					return null;
				}, this.acc);
			}
			else {
				((DisposableBean) this.bean).destroy(); // 最终调用bean的destroy方法(需要实现DisposableBean接口)
			}
		}
		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) {
		Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
		if (methodToInvoke != null) {
			invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
		}
	}
}

3、IOC容器关闭时是如何销毁Bean的

IOC容器关闭时会调用close()方法:

java 复制代码
// org.springframework.context.support.AbstractApplicationContext#close
@Override
public void close() {
	synchronized (this.startupShutdownMonitor) {
		doClose(); // 执行
		// If we registered a JVM shutdown hook, we don't need it anymore now:
		// We've already explicitly closed the context.
		if (this.shutdownHook != null) {
			try {
				Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
			}
			catch (IllegalStateException ex) {
				// ignore - VM is already shutting down
			}
		}
	}
}
java 复制代码
// org.springframework.context.support.AbstractApplicationContext#doClose
protected void doClose() {
	// Check whether an actual close attempt is necessary...
	if (this.active.get() && this.closed.compareAndSet(false, true)) {
		if (logger.isDebugEnabled()) {
			logger.debug("Closing " + this);
		}

		LiveBeansView.unregisterApplicationContext(this);

		try {
			// Publish shutdown event.
			publishEvent(new ContextClosedEvent(this));
		}
		catch (Throwable ex) {
			logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
		}

		// Stop all Lifecycle beans, to avoid delays during individual destruction.
		if (this.lifecycleProcessor != null) {
			try {
				this.lifecycleProcessor.onClose();
			}
			catch (Throwable ex) {
				logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
			}
		}

		// Destroy all cached singletons in the context's BeanFactory.
		destroyBeans(); // 调用getBeanFactory().destroySingletons();将所有单例进行销毁

		// Close the state of this context itself.
		closeBeanFactory();

		// Let subclasses do some final clean-up if they wish...
		onClose();

		// Reset local application listeners to pre-refresh state.
		if (this.earlyApplicationListeners != null) {
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Switch to inactive.
		this.active.set(false);
	}
}

6、@PreDestroy是怎么处理的

我们在第九节的第二小节中分析了@PostConstruct是怎么处理的,其实@PreDestroy类似。

CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,在InitDestroyAnnotationBeanPostProcessor中有postProcessBeforeDestruction方法,其实 @PreDestroy就是在此处进行处理的:

java 复制代码
// org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
	LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
	try {
		metadata.invokeDestroyMethods(bean, beanName);
	}
	catch (InvocationTargetException ex) {
		String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
		if (logger.isDebugEnabled()) {
			logger.warn(msg, ex.getTargetException());
		}
		else {
			logger.warn(msg + ": " + ex.getTargetException());
		}
	}
	catch (Throwable ex) {
		logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
	}
}

// org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata#invokeDestroyMethods
public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
	Collection<LifecycleElement> checkedDestroyMethods = this.checkedDestroyMethods;
	Collection<LifecycleElement> destroyMethodsToUse =
			(checkedDestroyMethods != null ? checkedDestroyMethods : this.destroyMethods);
	if (!destroyMethodsToUse.isEmpty()) {
		for (LifecycleElement element : destroyMethodsToUse) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
			}
			element.invoke(target);
		}
	}
}

5、总结分析

Spring Bean销毁阶段主要用于优雅停机。

十三、Spring Bean 垃圾收集

关于java的finalize方法,更多请移步下面文章中的 对象的finalization机制:
java垃圾回收算法超详细全解

想要Spring Bean 执行垃圾收集,需要:

1、关闭 Spring 容器(应用上下文)

2、执行 GC

3、Spring Bean 覆盖的 finalize() 方法被回调

finalize() 方法是在Object类中的方法,可以重写,在对象被回收时会被调用(新的jdk版本已经弃用了)。

这里说的Bean的垃圾收集,其实就是Java标准的JVM一个回收机制,与Spring关联性并不强了。

十四、总结Spring Bean的生命周期

BeanFactory 的默认实现为 DefaultListableBeanFactory,其中 Bean生命周期与方法映射如下:

• BeanDefinition 注册阶段 - registerBeanDefinition

• BeanDefinition 合并阶段 - getMergedBeanDefinition

• Bean 实例化前阶段 - resolveBeforeInstantiation

• Bean 实例化阶段 - createBeanInstance

• Bean 实例化后阶段 - populateBean

• Bean 属性赋值前阶段 - populateBean

• Bean 属性赋值阶段 - populateBean

• Bean Aware 接口回调阶段 - initializeBean

• Bean 初始化前阶段 - initializeBean

• Bean 初始化阶段 - initializeBean

• Bean 初始化后阶段 - initializeBean

• Bean 初始化完成阶段 - preInstantiateSingletons

• Bean 销毁前阶段 - destroyBean

• Bean 销毁阶段 - destroyBean

相关推荐
代码吐槽菌2 小时前
基于SSM的毕业论文管理系统【附源码】
java·开发语言·数据库·后端·ssm
豌豆花下猫2 小时前
Python 潮流周刊#78:async/await 是糟糕的设计(摘要)
后端·python·ai
YMWM_2 小时前
第一章 Go语言简介
开发语言·后端·golang
码蜂窝编程官方2 小时前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
hummhumm2 小时前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊2 小时前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
AuroraI'ncoding3 小时前
时间请求参数、响应
java·后端·spring
好奇的菜鸟3 小时前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
Alive~o.03 小时前
Go语言进阶&依赖管理
开发语言·后端·golang
许苑向上3 小时前
Dubbo集成SpringBoot实现远程服务调用
spring boot·后端·dubbo