一、Bean生命周期全景图
在深入细节之前,先了解Spring Bean生命周期的完整流程:


二、Bean的生成过程
1. 生成BeanDefinition:Spring扫描的底层实现
Spring启动时首先会扫描配置的包路径,将符合条件的类转换为BeanDefinition对象。
扫描流程图:
1.1 扫描流程详解
// 核心扫描方法:ClassPathScanningCandidateComponentProvider.scanCandidateComponents()
public Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
// 1. 获取包路径下所有.class文件的Resource对象
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
for (Resource resource : resources) {
// 2. 使用MetadataReaderFactory解析Resource
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
// 3. 使用过滤器进行筛选
if (isCandidateComponent(metadataReader)) {
// 4. 生成ScannedGenericBeanDefinition
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
// 5. 检查是否为接口/抽象类
if (isCandidateComponent(sbd)) {
candidates.add(sbd);
}
}
}
return candidates;
}
1.2 MetadataReader:类元数据读取器
Spring使用ASM技术读取类字节码,避免过早加载类到JVM。
// MetadataReader的主要功能
public interface MetadataReader {
ClassMetadata getClassMetadata(); // 类信息
AnnotationMetadata getAnnotationMetadata(); // 注解信息
Resource getResource(); // 资源信息
}
// 使用示例
SimpleMetadataReaderFactory factory = new SimpleMetadataReaderFactory();
MetadataReader reader = factory.getMetadataReader("com.service.UserService");
// 获取类信息
ClassMetadata classMetadata = reader.getClassMetadata();
System.out.println(classMetadata.getClassName()); // 类名
System.out.println(classMetadata.isInterface()); // 是否接口
System.out.println(classMetadata.isAbstract()); // 是否抽象类
// 获取注解信息
AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
Set<String> annotationTypes = annotationMetadata.getAnnotationTypes(); // 所有注解
1.3 筛选机制
扫描过程中会进行多级筛选:
-
excludeFilters:排除过滤器
-
includeFilters:包含过滤器
-
条件注解 :
@Conditional注解的条件匹配
1.4 BeanDefinition的多种来源
除了扫描,BeanDefinition还可以来自:
-
XML配置的
<bean>标签 -
@Bean注解的方法 -
编程式注册
2. 合并BeanDefinition:处理父子关系
Spring支持父子BeanDefinition,类似但不同于Java的继承。
<!-- 父BeanDefinition -->
<bean id="parent" class="com.service.Parent" scope="prototype"/>
<!-- 子BeanDefinition,继承父的scope属性 -->
<bean id="child" class="com.service.Child" parent="parent"/>
子BeanDefinition会继承父BeanDefinition的属性,在创建Bean前需要进行合并,得到完整的BeanDefinition。
3. 加载类:按需加载到JVM
// AbstractAutowireCapableBeanFactory中的加载逻辑
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName) throws ClassNotFoundException {
// 1. 检查是否已加载
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
// 2. 使用类加载器加载
return doResolveBeanClass(mbd, typesToMatch);
}
类加载器选择顺序:
-
当前线程的ClassLoader
-
ClassUtils类的ClassLoader
-
系统类加载器
4. 实例化前:第一个关键扩展点
@Component
public class CustomInstantiationAwareBeanPostProcessor
implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(
Class<?> beanClass, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("实例化前扩展点");
// 如果返回非null对象,Spring将跳过后续步骤
// return new UserService();
}
return null; // 返回null让Spring继续正常流程
}
}
重要特性:如果此方法返回非null对象,Spring将跳过:
-
正常实例化
-
依赖注入
-
直接执行初始化后步骤
5. 实例化:三种创建对象的方式
5.1 Supplier方式(编程式)
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition()
.getBeanDefinition();
// 设置Supplier
beanDefinition.setInstanceSupplier(new Supplier<Object>() {
@Override
public Object get() {
return new UserService();
}
});
context.registerBeanDefinition("userService", beanDefinition);
5.2 工厂方法方式
静态工厂方法:
<bean id="userService" class="com.service.UserService"
factory-method="createUserService"/>
public class UserService {
public static UserService createUserService() {
return new UserService();
}
}
实例工厂方法:
<bean id="commonService" class="com.service.CommonService"/>
<bean id="userService" factory-bean="commonService"
factory-method="createUserService"/>
public class CommonService {
public UserService createUserService() {
return new UserService();
}
}
5.3 推断构造方法
Spring会根据以下规则选择构造方法:
-
只有一个构造方法 → 使用该构造方法
-
多个构造方法且存在无参构造 → 使用无参构造
-
多个构造方法且指定了
@Autowired→ 使用指定构造方法
@Lookup注解的特殊处理:
@Component
public class UserService {
@Lookup("orderService")
public OrderService createOrderService() {
return null; // Spring会生成代理方法
}
}
如果存在@Lookup注解的方法,Spring会生成代理对象而非直接实例化。
6. BeanDefinition的后置处理
@Component
public class CustomMergedBeanDefinitionPostProcessor
implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(
RootBeanDefinition beanDefinition,
Class<?> beanType,
String beanName) {
if ("userService".equals(beanName)) {
// 修改BeanDefinition
beanDefinition.getPropertyValues()
.add("orderService", new OrderService());
}
}
}
Spring内置实现 :AutowiredAnnotationBeanPostProcessor在此阶段查找注入点并缓存。
7. 实例化后:第三个扩展点
@Component
public class CustomInstantiationAwareBeanPostProcessor
implements InstantiationAwareBeanPostProcessor {
@Override
public boolean postProcessAfterInstantiation(
Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
UserService userService = (UserService) bean;
userService.test();
}
return true; // 返回false将阻止属性填充
}
}
8. 自动注入与属性处理
此阶段处理@Autowired、@Resource、@Value等注解。
@Component
public class CustomInstantiationAwareBeanPostProcessor
implements InstantiationAwareBeanPostProcessor {
@Override
public PropertyValues postProcessProperties(
PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
for (Field field : bean.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(CustomInject.class)) {
field.setAccessible(true);
try {
field.set(bean, "注入的值");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return pvs;
}
}
9. Aware接口回调
@Component
public class UserService implements
BeanNameAware,
BeanFactoryAware,
BeanClassLoaderAware {
@Override
public void setBeanName(String name) {
System.out.println("Bean名称:" + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println("BeanFactory:" + beanFactory);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("ClassLoader:" + classLoader);
}
}
10. 初始化前:第四个扩展点
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(
Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("初始化前处理");
}
return bean;
}
}
Spring内置处理器在此阶段的工作:
-
InitDestroyAnnotationBeanPostProcessor:执行@PostConstruct方法 -
ApplicationContextAwareProcessor:处理其他Aware接口回调
11. 初始化:执行初始化逻辑
@Component
public class UserService implements InitializingBean {
private void customInit() {
System.out.println("自定义初始化方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet()");
}
}
两种初始化方式:
-
实现
InitializingBean接口的afterPropertiesSet()方法 -
BeanDefinition中指定的初始化方法
12. 初始化后:最后一个扩展点
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(
Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("初始化后处理");
// 可以返回代理对象
}
return bean;
}
}
重要:Spring AOP就是基于此扩展点实现的,返回的可能是代理对象而非原始对象。
三、Bean的销毁过程
1. 容器关闭触发销毁
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
// 使用Bean...
UserService userService = context.getBean(UserService.class);
userService.test();
// 关闭容器,触发Bean销毁
context.close();
2. 判断是否为DisposableBean
在Bean创建的最后阶段(初始化后),Spring会判断Bean是否需要销毁:
// 判断逻辑
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. 是否为原型Bean(原型Bean不管理销毁)
if (mbd.isPrototype()) {
return;
}
// 2. 检查是否实现了DisposableBean或AutoCloseable接口
boolean implementsDisposableBean = (bean instanceof DisposableBean);
boolean implementsAutoCloseable = (bean instanceof AutoCloseable);
// 3. 检查是否有destroyMethod
String destroyMethodName = mbd.getDestroyMethodName();
// 4. 检查DestructionAwareBeanPostProcessor
boolean hasDestructionAwareBeanPostProcessors =
hasDestructionAwareBeanPostProcessors();
if (implementsDisposableBean || implementsAutoCloseable ||
destroyMethodName != null || hasDestructionAwareBeanPostProcessors) {
// 适配为DisposableBeanAdapter并注册
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd,
getBeanPostProcessors(), getAccessControlContext()));
}
}
3. 适配器模式的应用
由于销毁方式多样,Spring使用DisposableBeanAdapter进行统一适配:
// DisposableBeanAdapter统一处理各种销毁方式
class DisposableBeanAdapter implements DisposableBean {
private final Object bean;
private final String beanName;
private final RootBeanDefinition beanDefinition;
@Override
public void destroy() throws Exception {
// 1. 调用DestructionAwareBeanPostProcessor
// 2. 调用DisposableBean.destroy()
// 3. 调用AutoCloseable.close()
// 4. 调用自定义destroy-method
}
}
4. 销毁执行流程
// DefaultSingletonBeanRegistry.destroySingletons()
public void destroySingletons() {
// 1. 发布ContextClosedEvent事件
publishEvent(new ContextClosedEvent(this));
// 2. 调用LifecycleProcessor的onClose()
getLifecycleProcessor().onClose();
// 3. 销毁单例Bean
synchronized (this.singletonObjects) {
// 遍历所有需要销毁的Bean
for (String beanName : disposableBeans.keySet()) {
DisposableBean disposableBean = disposableBeans.remove(beanName);
try {
// 从单例池移除
removeSingleton(beanName);
// 调用销毁方法
disposableBean.destroy();
// 处理依赖此Bean的其他Bean
destroySingleton(beanName);
// 处理内部Bean
destroyBean(beanName, disposableBean, null);
} catch (Exception e) {
logger.error("销毁Bean失败: " + beanName, e);
}
}
// 清理缓存
clearSingletonCache();
}
}
5. 多种销毁方式示例
5.1 实现DisposableBean接口
@Component
public class UserService implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean.destroy()被调用");
// 释放资源
}
}
5.2 实现AutoCloseable接口
@Component
public class DataSourceService implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("AutoCloseable.close()被调用");
// 关闭连接
}
}
5.3 指定destroy-method
<bean id="userService" class="com.service.UserService"
destroy-method="cleanup"/>
public class UserService {
public void cleanup() {
System.out.println("自定义销毁方法被调用");
}
}
5.4 使用@PreDestroy注解
@Component
public class UserService {
@PreDestroy
public void preDestroy() {
System.out.println("@PreDestroy方法被调用");
}
}
6. 销毁过程中的依赖处理
如果Bean A依赖Bean B,当Bean B被销毁时:
-
检查Bean A是否也依赖Bean B
-
如果依赖,则Bean A也需要被销毁
-
递归处理所有依赖关系
四、完整生命周期总结
BeanPostProcessor执行顺序总结
-
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() - 实例化前
-
构造方法实例化 - 创建对象
-
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition() - 处理BeanDefinition
-
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() - 实例化后
-
自动注入 - 处理依赖关系
-
InstantiationAwareBeanPostProcessor.postProcessProperties() - 属性处理
-
Aware接口回调 - BeanNameAware、BeanFactoryAware等
-
BeanPostProcessor.postProcessBeforeInitialization() - 初始化前
-
初始化 - InitializingBean.afterPropertiesSet()和init-method
-
BeanPostProcessor.postProcessAfterInitialization() - 初始化后
设计模式应用总结
-
模板方法模式:Bean创建流程的固定骨架
-
策略模式:多种实例化方式(Supplier、工厂方法、构造方法)
-
适配器模式:DisposableBeanAdapter统一各种销毁方式
-
观察者模式:事件发布与监听
-
工厂模式:BeanFactory创建和管理Bean
五、性能优化与最佳实践
1. 使用ASM避免类加载
// Spring使用ASM读取类元数据,避免启动时加载所有类
MetadataReader reader = metadataReaderFactory.getMetadataReader(className);
// 仅读取字节码,不加载到JVM
2. 合理使用扩展点
-
InstantiationAwareBeanPostProcessor:控制实例化过程
-
MergedBeanDefinitionPostProcessor:修改BeanDefinition
-
BeanPostProcessor:在初始化前后添加逻辑
3. 避免循环依赖
-
使用setter注入而非构造器注入
-
使用
@Lazy注解延迟加载 -
重新设计代码结构
4. 合理配置Bean作用域
-
无状态Bean使用单例(默认)
-
有状态Bean考虑使用原型
-
Web环境注意request、session作用域
六、调试与监控技巧
1. 使用JFR监控Bean生命周期
# 启动应用时添加JFR参数
java -XX:+FlightRecorder -XX:StartFlightRecording=duration=60s,filename=recording.jfr -jar app.jar
2. 添加自定义监控
@Component
public class BeanLifecycleMonitor implements BeanPostProcessor {
private Map<String, Long> creationTimes = new ConcurrentHashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
creationTimes.put(beanName, System.currentTimeMillis());
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
Long startTime = creationTimes.get(beanName);
if (startTime != null) {
long duration = System.currentTimeMillis() - startTime;
System.out.println(beanName + " 创建耗时: " + duration + "ms");
}
return bean;
}
}
七、常见问题与解决方案
Q1: Bean创建过程卡住怎么办?
排查步骤:
-
检查
postProcessBeforeInstantiation()是否返回了对象 -
检查循环依赖
-
检查
@DependsOn注解的依赖关系 -
使用线程转储分析
Q2: 销毁方法未执行?
可能原因:
-
Bean是原型作用域(Spring不管理原型Bean的销毁)
-
容器未正常关闭
-
销毁方法抛出了异常
Q3: 如何优雅地关闭Spring容器?
// 1. 注册Shutdown Hook
context.registerShutdownHook();
// 2. 编程式关闭
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
context.close();
}));
八、总结
Spring Bean的生命周期是一个精心设计的过程,包含了多个扩展点和回调机制。理解这个过程对于:
-
深度使用Spring框架:掌握各个扩展点的作用
-
排查复杂问题:快速定位Bean创建、初始化、销毁过程中的问题
-
性能优化:合理配置Bean,避免不必要的开销
-
框架扩展:基于Spring的扩展机制开发自己的功能
