文章目录
写在前面
书接上文
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的回调接口(下面的列表是回调的顺序):
- 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中定义一个属性来保存它。
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