在 Spring 框架中,容器可以对 Singleton 作用域下的 bean 进行生命周期管理,对 bean 的创建、初始化和销毁进行控制。本文讲述 bean 的生命周期全过程,详细描述了生命周期过程中 spring 开放的自定义切入接口。
生命周期流程图:

一、定义Bean
在程序启动最初,Spring 可通过 xml 文件、注解或 javaApi 的方式创建 BeanDefinition。
BeanFactoryPostProcessor 是 bean 工厂的后置处理器,在 BeanDefinition 全部扫描创建完成后执行,可以在容器的 bean 创建之前修改 bean 工厂和 BeanDefinition。
二、实例化与属性注入
当客户向容器请求一个尚未初始化的 bean 时,或初始化 bean 时需要注入另一个尚末初始化的依赖时,容器就会调用 doCreateBean 方法通过反射的方式创建出一个 bean 对象。
bean 实例创建之后,doCreateBean 方法通过调用 populateBean 方法对这个 bean 进行属性填充。
三、初始化Bean
Bean 初始化过程对应 initializeBean 方法,将被 doCreateBean 方法调用。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 执行 BeanNameAware、BeanClassLoaderAware和BeanFactoryAware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// 执行 BeanPostProcessor 接口的 postProcessBeforeInitialization 方法。
// 除了上述的三个 Aware 接口,其余的 Aware 接口通过 BeanPostProcessor 接口实现,具体实现类为
// ApplicationContextAwareProcessor。
// 初始化 bean 的扩展插入注解 @PostConstruct 通过 CommonAnnotationBeanPostProcessor
// 接口实现。
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 执行 InitializingBean 接口和 init-method 参数两种扩展方式插入的方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 执行 BeanPostProcessor 接口的 postProcessAfterInitialization 方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
如上源码所示:
-
初始化
bean最初,容器会检测bean是否实现了内置的xxxAware接口,如果实现了则执行相应的接口方法。通过
xxxAware接口,可以让bean拿到Spring容器的一些资源。常见
Aware接口:- ApplicationContextAware:获取容器本身
ApplicationContext对象; - ApplicationEventPublisherAware:获取事件发布器的接口;
- BeanClassLoaderAware:获取加载当前
bean的类加载器; - BeanFactoryAware: 获取当前
bean的BeanFactory实例,可以用来手动注册bean; - BeanNameAware:在获取
bean在容器中的的名称; - ResourceLoaderAware:获取
ResourceLoader实例,获取资源加载器读取资源文件。
- ApplicationContextAware:获取容器本身
-
在执行完
BeanNameAware、BeanClassLoaderAware和BeanFactoryAware之后,执行初始化扩展之前,spring执行BeanPostProcessor后置处理器的postProcessBeforeInitialization方法。值得注意的是,
Aware、初始化扩展方法与BeanPostProcessor职责并非明确划分的,他们也通过BeanPostProcessor实现功能。除了上述的三种
Aware接口,其余的Aware接口都是通过BeanPostProcessor的实现类ApplicationContextAwareProcessor在此处完成的调用。初始化扩展注解
@PostConstruct通过CommonAnnotationBeanPostProcessor实现。通过控制
BeanPostProcessor列表的顺序,从而使初始化的执行步骤有序。

-
在初始化
bean时spring提供了三种扩展方式,三种扩展方式可同时使用,但不能同时指向同一个方法,多个扩展指向同一个方法这个方法也只会执行一次。扩展方法执行顺序为:
@PostConstruct注解 ->InitializingBean接口 ->init-method参数指定。 -
在执行自定义初始化方法之后,
spring最后执行BeanPostProcessor后置处理器的postProcessAfterInitialization方法,完成bean的初始化过程。
四、销毁Bean
在销毁 bean 时 spring 提供了三种扩展方式,三种扩展方式可同时使用,但不能同时指向同一个方法,多个扩展指向同一个方法这个方法也只会执行一次。
扩展方法执行顺序为:@PreDestroy 注解 -> DisposableBean 接口 -> destroy-method 参数指定。
五、测试代码
BeanProcess 实体类:
package com.nineya.spring.bean.lifecycle.entity;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Getter
@Setter
@ToString
public class BeanProcess implements BeanNameAware, ResourceLoaderAware, InitializingBean, DisposableBean {
private String name;
@PostConstruct
public void init() {
System.out.println("Bean @PostConstruct: name = " + name);
}
@PostConstruct
public void init2() {
System.out.println("Bean @PostConstruct2: name = " + name);
}
@PreDestroy
public void preDestroy() {
System.out.println("Bean @PreDestroy: name = " + name);
}
@PreDestroy
public void preDestroy2() {
System.out.println("Bean @PreDestroy2: name = " + name);
}
@Override
public void destroy() {
System.out.println("Bean DisposableBean: name = " + name);
}
@Override
public void afterPropertiesSet() {
System.out.println("Bean InitializingBean: name = " + name);
}
public void initMethod() {
System.out.println("Bean InitMethod: name = " + name);
}
public void destroyMethod() {
System.out.println("Bean DestroyMethod: name = " + name);
}
@Override
public void setBeanName(String beanName) {
System.out.println("Bean BeanNameAware: beanName = " + beanName + ", name = " + name);
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("Bean ResourceLoaderAware: resourceLoader = " + resourceLoader + ", name = " + name);
}
}
NineyaBeanFactoryPostProcessor 后置处理器:
package com.nineya.spring.bean.lifecycle.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class NineyaBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("后置处理器BeanFactoryPostProcessor: postProcessBeanFactory: " + String.join(",", beanFactory.getBeanDefinitionNames()));
}
}
NineyaBeanPostProcessor 后置处理器:
package com.nineya.spring.bean.lifecycle.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class NineyaBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("后置处理器BeanPostProcessor: postProcessAfterInitialization(" + beanName + ") :" + bean);
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("后置处理器BeanPostProcessor: postProcessBeforeInitialization(" + beanName + ") :" + bean);
return bean;
}
}
BeanLifecycleConfiguration 配置类:
package com.nineya.spring.bean.lifecycle.config;
import com.nineya.spring.bean.lifecycle.entity.BeanProcess;
import com.nineya.spring.bean.lifecycle.processor.NineyaBeanFactoryPostProcessor;
import com.nineya.spring.bean.lifecycle.processor.NineyaBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanLifecycleConfiguration {
@Bean(value = "test", initMethod = "initMethod", destroyMethod = "destroyMethod")
public BeanProcess beanProcess() {
BeanProcess beanProcess = new BeanProcess();
beanProcess.setName("test");
return beanProcess;
}
@Bean
public NineyaBeanPostProcessor nineyaBeanPostProcessor() {
return new NineyaBeanPostProcessor();
}
@Bean
public NineyaBeanFactoryPostProcessor nineyaBeanFactoryPostProcessor() {
return new NineyaBeanFactoryPostProcessor();
}
}
入口类:
package com.nineya.spring.bean.lifecycle;
import com.nineya.spring.bean.lifecycle.entity.BeanProcess;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BeanLifecycleMain {
public static void main(String[] args) {
System.out.println("## 创建容器");
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
System.out.println("## 扫描Bean注解");
context.scan(BeanLifecycleMain.class.getPackage().getName());
context.refresh();
System.out.println("## 通过class取得bean");
BeanProcess beanProcess = context.getBean(BeanProcess.class);
System.out.println(beanProcess + " : " + beanProcess.hashCode());
System.out.println("## 通过bean名称取得bean");
beanProcess = (BeanProcess) context.getBean("test");
System.out.println(beanProcess + " : " + beanProcess.hashCode());
System.out.println("## 销毁Bean");
((DefaultListableBeanFactory)context.getBeanFactory()).destroySingleton("test");
System.out.println("## 取得beanDefinition");
BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("test");
System.out.println("beanDefinition : " + beanDefinition);
System.out.println("## 通过bean名称取得bean");
beanProcess = (BeanProcess) context.getBean("test");
System.out.println(beanProcess + " : " + beanProcess.hashCode());
}
}
执行结果可反应上述生命周期过程:
## 创建容器
## 扫描Bean注解
后置处理器BeanFactoryPostProcessor: postProcessBeanFactory: org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,beanLifecycleConfiguration,nineyaBeanFactoryPostProcessor,nineyaBeanPostProcessor,test
Bean BeanNameAware: beanName = test, name = test
Bean ResourceLoaderAware: resourceLoader = org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0, started on Tue Aug 08 15:47:54 CST 2023, name = test
后置处理器BeanPostProcessor: postProcessBeforeInitialization(test) :BeanProcess(name=test)
Bean @PostConstruct: name = test
Bean @PostConstruct2: name = test
Bean InitializingBean: name = test
Bean InitMethod: name = test
后置处理器BeanPostProcessor: postProcessAfterInitialization(test) :BeanProcess(name=test)
## 通过class取得bean
BeanProcess(name=test) : 346224929
## 通过bean名称取得bean
BeanProcess(name=test) : 346224929
## 销毁Bean
Bean @PreDestroy2: name = test
Bean @PreDestroy: name = test
Bean DisposableBean: name = test
Bean DestroyMethod: name = test
## 取得beanDefinition
beanDefinition : Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=beanLifecycleConfiguration; factoryMethodName=beanProcess; initMethodName=initMethod; destroyMethodName=destroyMethod; defined in com.nineya.spring.bean.lifecycle.config.BeanLifecycleConfiguration
## 通过bean名称取得bean
Bean BeanNameAware: beanName = test, name = test
Bean ResourceLoaderAware: resourceLoader = org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0, started on Tue Aug 08 15:47:54 CST 2023, name = test
后置处理器BeanPostProcessor: postProcessBeforeInitialization(test) :BeanProcess(name=test)
Bean @PostConstruct: name = test
Bean @PostConstruct2: name = test
Bean InitializingBean: name = test
Bean InitMethod: name = test
后置处理器BeanPostProcessor: postProcessAfterInitialization(test) :BeanProcess(name=test)
BeanProcess(name=test) : 63468833