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

写在前面

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

Spring Bean生命周期——从源码角度详解Spring Bean的生命周期下

七、Spring Bean 属性赋值前阶段

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

@Nullable
private MutablePropertyValues propertyValues;

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

@Nullable
private ConstructorArgumentValues constructorArgumentValues;

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

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

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

/**
 * 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、代码实例

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方法我们接下来继续分析该方法

// 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的回调接口下面的列表是回调的顺序

  • BeanNameAwarebean名称回调
  • BeanClassLoaderAwarebean对应的classLoader回调
  • BeanFactoryAwareBeanFactory回调
  • EnvironmentAwareEnvironment环境回调
  • EmbeddedValueResolverAwareEmbeddedValueResolver回调实际上存在的是StringValueResolver
  • ResourceLoaderAwareResourceLoader回调
  • ApplicationEventPublisherAwareApplicationEventPublisher回调
  • MessageSourceAwareMessageSource回调用于Spring国际化
  • ApplicationContextAwareApplicationContext回调注入ApplicationContext

1、BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

代码实例

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

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方法我们回顾一下

// 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方法

// 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接口的回调方法

// 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容器创建流程

// 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。

@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容器下面简单一个实例

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方法。

代码实例

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即可。

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

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

// 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

// 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

// 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() 方法
  • 自定义初始化方法

代码实例

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接下来我们继续分析

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

// 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进行了处理。

// 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中

@Nullable
private Class<? extends Annotation> initAnnotationType;

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

// 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就是在此处进行处理的

// 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初始化前阶段用法相同。

代码实例

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方法

// 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。

// 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、代码实例

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接口

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

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

// 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);方法中执行的

// 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的销毁才能执行该逻辑。

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方法

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

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

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

最终都会调用DisposableBeanAdapter的destroy方法

// 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、代码实例

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方法。

// 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()方法

// 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
			}
		}
	}
}
// 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就是在此处进行处理的

// 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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring