深度解析 Spring Bean 生命周期
在 Spring 框架的体系中,Bean 的生命周期管理是支撑应用稳定运行的核心逻辑。它精细把控着 Bean 从 “定义蓝图” 到 “销毁回收” 的每一步,深刻影响着依赖注入、AOP 增强、资源管理等关键功能。本文将结合实例化策略(构造函数、工厂方法)与属性注入(Setter 注入),完整拆解 Bean 生命周期的全流程,带你看透 Spring 容器的运作本质。
Bean 实例化的基本流程
- 加载xml配置文件,解析获取配置中的每个的信息,封装成一个个的 BeanDefinition 对象;
- 将 BeanDefinition 存储在一个名为 beanDefinitionMap 的Map<String,BeanDefinition>中;
- ApplicationContext 底层遍历 beanDefinitionMap,创建 Bean 实例对象;
- 创建好的 Bean 实例对象,被存储到一个名为singletonObjects的Map<String,Object>中;
- 当执行 applicationContext.getBean(beanName) 时,从singletonObjects去匹配Bean实例返回
一、Bean 生命周期全景概览
Spring Bean 生命周期可拆解为 “定义→实例化→初始化→使用→销毁” 五大阶段,每个阶段又包含细分步骤,共同构建出 Bean 的完整生命周期:
二、阶段 1:BeanDefinition 加载(“定义蓝图”)
1. 核心逻辑
Spring 启动时,通过 BeanDefinitionReader(如 XML 解析器、注解扫描器 )解析配置(XML / 注解),将 Bean 的 “元数据”(类名、作用域、依赖、初始化方法等)转化为 BeanDefinition,存入 BeanDefinitionRegistry(容器的 “蓝图仓库” )。
2. 代码 / 配置示例
<!-- XML 配置定义 Bean -->
<bean id="userService" class="com.example.UserService"/>
// 注解扫描定义 Bean(@Service 会被转化为 BeanDefinition)
@Service
public class UserService {}
3. 作用
这一步是 “定义 Bean” 而非 “创建实例”,BeanDefinition 是后续实例化、注入的 “蓝图”,决定了 Bean 的基础配置。
三、阶段 2:实例化(构造 / 工厂方法创建对象)
实例化是 Bean 从 “蓝图” 到 “内存对象” 的第一步,Spring 提供 两种核心策略,按需选择创建方式:
策略 1:构造函数实例化(默认首选)
(1)核心逻辑
- 无参构造:若 Bean 无特殊配置,Spring 默认调用 无参构造函数 创建实例。
- 有参构造:若 Bean 定义了有参构造(或通过 @Autowired 标记),Spring 会自动解析参数依赖,从容器中查找匹配的 Bean 注入,再调用构造函数创建实例。
(2)代码示例
public class UserService {private UserDao userDao;// 有参构造 + 依赖注入(Spring 自动识别)@Autowiredpublic UserService(UserDao userDao) {this.userDao = userDao;System.out.println("UserService 有参构造执行,注入 UserDao");}
}
如果不用注解的,对应的XML配置实现构造函数注入:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 1. 定义UserDao的Bean --><bean id="userDao" class="com.example.UserDao"/><!-- 2. 定义UserService的Bean,并通过构造函数注入UserDao --><bean id="userService" class="com.example.UserService"><!-- 通过constructor-arg指定构造函数参数,ref引用已定义的userDao Bean --><constructor-arg ref="userDao"/></bean></beans>
(3)使用场景
简单 Bean 创建、依赖需 “强制注入” 的场景(如 Service 依赖 Dao,构造时必须传入 )。
策略 2:工厂方法实例化(复杂场景适配)
(1)核心逻辑
通过 工厂类 / 工厂方法 创建 Bean,Spring 调用指定的工厂方法(静态 / 实例方法)生成实例,支持灵活的自定义逻辑。
(2)代码示例
// 工厂类
public class UserServiceFactory {private UserService service; // 通过setter 注入public void setUserService(UserService service) {this.service = service;}public UserService createUserService() {// 自定义初始化逻辑service.setMaxRetry(3); //将其 maxRetry(最大重试次数)属性设置为 3。return service;}
}
(3)适用场景
- 第三方库对象创建(无法修改构造函数,需通过工厂封装 );
- 复杂初始化逻辑(如设置默认参数、连接资源 )。
四、阶段 3:属性注入(Setter / 构造函数填充依赖)
实例化生成 “空对象” 后,Spring 会为 Bean 注入属性(依赖的其他 Bean、基本类型值 ),支持 两种核心方式:
方式 1:Setter 注入(灵活可选)
(1)核心逻辑
通过 setXxx() 方法注入依赖,需配合 无参构造(或工厂方法创建实例后执行 ),适合 “可选依赖” 或 “需动态修改” 的场景。
(2)代码示例
public class UserService {private UserDao userDao;private int maxRetry;// 无参构造(实例化时执行)public UserService() {System.out.println("UserService 无参构造执行");}// Setter 注入 UserDao(依赖 Bean)@Autowiredpublic void setUserDao(UserDao userDao) {this.userDao = userDao;System.out.println("Setter 注入 UserDao");}// Setter 注入基本类型(maxRetry)public void setMaxRetry(int maxRetry) {this.maxRetry = maxRetry;System.out.println("Setter 注入 maxRetry:" + maxRetry);}
}
(3)适用场景
- 依赖为 “可选”(如部分属性可后续动态设置 );
- 兼容旧代码(无法修改构造函数,通过 Setter 注入适配 )。
方式 2:构造函数注入(强制依赖)
(1)核心逻辑
依赖通过 构造函数参数 注入(与 “构造函数实例化” 协同 ),适合 “强制依赖” 场景(依赖不注入则 Bean 无法工作 )。
(2)代码示例
public class UserService {private UserDao userDao;// 有参构造 + 依赖注入(强制传入 UserDao)public UserService(UserDao userDao) {this.userDao = userDao;System.out.println("构造函数注入 UserDao");}
}
(3)适用场景
- 依赖为 “必须项”(如数据库连接,构造时必须初始化 );
- 需避免 “依赖空指针” 的严格场景。
五、阶段 4:初始化(Aware、后置处理器、自定义逻辑)
实例化、注入完成后,Bean 进入 初始化阶段,执行一系列增强和自定义逻辑,包含 5 大关键步骤:
步骤 1:Aware 接口回调(感知容器)
(1)核心逻辑
若 Bean 实现 Aware 子接口(如 BeanNameAware、ApplicationContextAware ),Spring 会回调对应方法,让 Bean 主动获取容器信息(名称、上下文、工厂等 )。
(2)代码示例
public class UserService implements BeanNameAware {private String beanName;@Overridepublic void setBeanName(String name) {this.beanName = name;System.out.println("Aware 回调:Bean 名称为 " + name);}
}
步骤 2:BeanPostProcessor 前置处理(初始化前增强)
(1)核心逻辑
Spring 遍历所有 BeanPostProcessor(后置处理器 ),执行 postProcessBeforeInitialization,可在初始化前 增强 / 修改 Bean(如统一打日志、校验属性 )。
(2)代码示例
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {if (bean instanceof UserService) {System.out.println("初始化前增强:" + beanName);}return bean;}
}
步骤 3:InitializingBean 回调(afterPropertiesSet)
(1)核心逻辑
若 Bean 实现 InitializingBean 接口,Spring 调用 afterPropertiesSet 执行 自定义初始化逻辑(如依赖校验、资源初始化 )。
(2)代码示例
public class UserService implements InitializingBean {@Overridepublic void afterPropertiesSet() {System.out.println("InitializingBean 回调:执行自定义初始化");}
}
步骤 4:@PostConstruct 或 init-method(自定义初始化)
(1)核心逻辑
通过 @PostConstruct 注解或 XML 配置 init-method,执行 开发者自定义的初始化逻辑(如加载缓存、启动线程 )。
(2)代码示例
@Service
public class UserService {@PostConstructpublic void init() {System.out.println("@PostConstruct 执行:初始化缓存");}
}
步骤 5:BeanPostProcessor 后置处理(初始化后增强,如 AOP)
(1)核心逻辑
再次遍历 BeanPostProcessor,执行 postProcessAfterInitialization,最终增强 Bean(如 Spring AOP 在此生成代理对象,织入切面逻辑 )。
(2)典型场景
Spring AOP 的 AnnotationAwareAspectJAutoProxyCreator 在此步骤为 @Transactional 标注的 Bean 创建代理,实现事务功能。
六、阶段 5:使用(业务调用,Bean 投入运行)
初始化完成后,Bean 进入 “可用状态”,可通过以下方式被业务调用:
- 依赖注入:其他 Bean 通过 @Autowired 注入使用;
- 手动获取:通过 ApplicationContext.getBean("userService") 直接获取;
- 事件驱动:作为监听器接收并处理容器事件。
七、阶段 6:销毁(容器关闭,资源回收)
容器关闭时,Spring 触发 销毁逻辑,释放 Bean 占用的资源(如数据库连接、线程池 ),支持以下方式:
方式 1:DisposableBean 回调(destroy 方法)
(1)核心逻辑
若 Bean 实现 DisposableBean 接口,Spring 调用 destroy 方法执行销毁。
(2)代码示例
public class UserService implements DisposableBean {@Overridepublic void destroy() {System.out.println("DisposableBean 回调:释放资源");}
}
方式 2:@PreDestroy 或 destroy-method(自定义销毁)
(1)核心逻辑
通过 @PreDestroy 注解或 XML 配置 destroy-method,执行 自定义销毁逻辑(如关闭连接、停止线程 )。
(2)代码示例
@Service
public class UserService {@PreDestroypublic void cleanUp() {System.out.println("@PreDestroy 执行:清理缓存");}
}
八、全流程总结:Bean 生命周期的 “建造者思维”
Spring Bean 生命周期是一场 “蓝图定义→实例创建→依赖注入→增强初始化→业务使用→销毁回收” 的完整流程,每个阶段都为 Bean 的 “可用” 与 “可控” 服务:
- BeanDefinition:定义 Bean 的 “蓝图”,决定基础配置;
- 实例化:通过构造 / 工厂方法将 “蓝图” 转化为 “内存对象”;
- 属性注入:填充依赖,让 Bean 具备 “协作能力”;
- 初始化:通过 Aware、后置处理器、自定义逻辑,让 Bean 具备 “业务能力”;
- 使用:Bean 投入业务,支撑应用运行;
- 销毁:容器关闭时回收资源,保证应用 “优雅退出”。
理解这一流程,不仅能让你精准把控 Bean 的创建与管理,更能在复杂场景中(如 AOP 失效排查、自定义 Bean 增强 )快速定位问题,让 Spring 框架成为你构建稳健应用的 “得力助手”。