Spring Bean 的生命周期是指 Bean 从创建、初始化、使用到销毁的完整过程,核心由 Spring 容器全程管理,主要可分为 4 个核心阶段,关键节点需结合初始化/销毁方法和后置处理器。

spring Bean流程图:
1. Bean 的创建阶段
css
容器通过 XML 配置、注解(@Component 等)或 Java 配置类 扫描并定位 Bean 的定义信息(BeanDefinition)。
根据 Bean 的作用域(默认单例),容器在启动时(单例 Bean)或首次获取时(原型 Bean),通过反射调用 Bean 的 无参构造方法 创建实例对象。
2. Bean 的初始化阶段(核心)
初始化是 Bean 功能完善的关键步骤,按顺序执行以下操作:
typescript
1.设置属性(依赖注入):容器将 Bean 依赖的其他对象(如 @Autowired 标注的属性)注入到当前 Bean 中。
2.调用Aware接口方法:若 Bean 实现了 BeanNameAware、BeanFactoryAware 等接口,容器会主动调用接口方法,传递 Bean 名称、BeanFactory 等容器信息(如 setBeanName(String name))。
3.调用BeanPostProcessor前置方法:容器中的 BeanPostProcessor 接口实现类,会调用 postProcessBeforeInitialization(Object bean, String beanName),对 Bean 进行初始化前的自定义处理(如AOP代理前置准备)。
4.执行自定义初始化方法:
若通过 XML 配置(init-method 属性)、注解(@PostConstruct)或实现 InitializingBean 接口(afterPropertiesSet() 方法)定义了初始化逻辑,容器会依次执行这些方法。
5.调用BeanPostProcessor后置方法:BeanPostProcessor 实现类调用 postProcessAfterInitialization(Object bean, String beanName),完成初始化后的最终处理(如生成AOP代理对象)。
至此,Bean 已完全初始化,可被容器或业务代码获取并使用。
3. Bean 的使用阶段
初始化完成的 Bean 存储在容器中,根据作用域提供服务:
scss
单例 Bean:全程只有一个实例,容器启动后持续存在,供多次获取和使用。
原型 Bean:每次调用 getBean() 都会创建新实例,使用后由 JVM 垃圾回收(Spring 不管理原型 Bean 的销毁)。
4. Bean 的销毁阶段(仅单例 Bean)
当 Spring 容器关闭(如应用停止)时,单例 Bean 会触发销毁流程:
scss
1.若 Bean 实现 DisposableBean 接口,容器调用其 destroy() 方法。
2.执行自定义销毁方法:通过 XML 配置(destroy-method 属性)或注解(@PreDestroy)定义的销毁逻辑(如释放数据库连接、关闭线程池)。
3.销毁完成后,Bean 实例被 JVM 垃圾回收。
代码实例:
Book
csharp
public class Book implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware {
private String title;
//空参
public Book() {
System.out.println("1.实例化 Book 对象");
}
//set
public void setTitle(String title) {
this.title = title;
System.out.println("2.依赖注入(属性填充) 设置 Book 对象的 title 属性,title = " + title);
}
//get
public String getTitle() {
return title;
}
//初始化方法
public void myInit() {
// System.out.println("3.初始化方法 Book 对象");
if (title == null) {
title = "默认书籍"; // 如果没有设置标题,则使用默认标题
System.out.println("3 初始化方法 Book 对象> 默认标题是:" + title);
} else {
System.out.println("3 初始化方法 Book 对象> 标题是:" + title);
}
}
//销毁方法
public void myDestroy() {
System.out.println("5.销毁方法 Book 对象");
}
public void afterPropertiesSet() throws Exception {
System.out.println("2.9.初始化方法 Book 对象 -- afterPropertiesSet");
if (title == null) {
title = "默认书籍"; // 如果没有设置标题,则使用默认标题
// System.out.println("4.1 初始化方法 Book 对象> 默认标题是:" + title);
} else {
// System.out.println("4.1 初始化方法 Book 对象> 标题是:" + title);
}
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("2.2 设置 Bean 工厂为:" + beanFactory.getClass().getName());
}
public void setBeanName(String s) {
System.out.println("2.1 设置 Bean 名称为:" + s);
}
public void destroy() throws Exception {
System.out.println("4.9 销毁方法 Book 对象 -- DisposableBean");
// 在这里可以执行一些清理操作,例如关闭资源等
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("2.3 设置 ApplicationContext 为:" + applicationContext.getClass().getName());
}
}
BookProcessor
typescript
public class BookProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 在初始化之前执行
if (bean instanceof Book) {
System.out.println("2.5 -- Before Initialization: " + beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 在初始化之后执行
if (bean instanceof Book) {
System.out.println("3.5 -- After Initialization: " + beanName);
}
return bean;
}
}
spring.xml
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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 定义一个book bean-->
<bean id="book" class="com.example.demo.bean.Book" init-method="myInit" destroy-method="myDestroy">
<property name="title" value="Java编程思想"/>
</bean>
<!-- 定义一个BookProcessor bean -->
<bean id="bookProcessor" class="com.example.demo.bean.BookProcessor"/>
</beans>
测试类
csharp
@Test
public void test4() {
// 测试类
//通过注解的方式生成bean的测试
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
// 获取 book 对象
Book book = context.getBean(Book.class);
// 4.使用bean
// System.out.println("8.使用Bean Cat 对象,name = " + cat.getName());
System.out.println("4.使用Bean Book 对象,name = " + book.getTitle());
// 关闭容器
((ClassPathXmlApplicationContext) context).close();
// 5.销毁 Cat 对象
// 注意:在使用 ClassPathXmlApplicationContext 时,销毁方法会在 close() 方法调用时自动执行
}
运行结果如下:
ini
1.实例化 Book 对象
2.依赖注入(属性填充) 设置 Book 对象的 title 属性,title = Java编程思想
2.1 设置 Bean 名称为:book
2.2 设置 Bean 工厂为:org.springframework.beans.factory.support.DefaultListableBeanFactory
2.3 设置 ApplicationContext 为:org.springframework.context.support.ClassPathXmlApplicationContext
2.5 -- Before Initialization: book
2.9.初始化方法 Book 对象 -- afterPropertiesSet
3 初始化方法 Book 对象> 标题是:Java编程思想
3.5 -- After Initialization: book
4.使用Bean Book 对象,name = Java编程思想
4.9 销毁方法 Book 对象 -- DisposableBean
5.销毁方法 Book 对象