在 Spring IoC 容器中,Bean 的生命周期是一个非常重要的概念,它定义了 Bean 从创建到销毁的完整过程。了解这一过程有助于开发者在合适的阶段对 Bean 进行定制化处理(如初始化资源、销毁资源等)。以下是 Bean 生命周期的详细流程及关键阶段说明:
一、Bean 生命周期的完整流程
1. 容器启动与 Bean 定义加载
- 阶段说明:Spring 容器启动时,会解析配置文件(如 XML)或注解(如
@Configuration),加载 Bean 的定义信息(如类名、属性值、依赖关系等)。 - 关键动作:
- 容器读取
BeanDefinition( Bean 的元数据描述)。 - 注册 Bean 到容器的注册表中。
- 容器读取
2. Bean 实例化(Instantiation)
- 阶段说明:容器根据
BeanDefinition创建 Bean 实例。 - 实例化方式:
- 构造函数实例化:通过无参构造函数或指定构造函数创建对象(如
@Bean注解或 XML 中<constructor-arg>)。 - 工厂方法实例化:调用静态工厂方法或实例工厂方法创建对象(如
factory-method属性)。
- 构造函数实例化:通过无参构造函数或指定构造函数创建对象(如
- 示例:
// 构造函数实例化 public class UserService { public UserService() { System.out.println("UserService 实例化"); } } // 工厂方法实例化 public class BeanFactory { public static UserService createService() { return new UserService(); } }
3. 属性填充(Population of Properties)
- 阶段说明:为 Bean 的属性设置值或注入依赖对象。
- 依赖注入方式:
- setter 注入:通过
setter方法注入(如 XML 中<property>或@Autowired注解在 setter 上)。 - 构造器注入:通过构造函数参数注入(如
@Autowired注解在构造函数上)。 - 字段注入:直接在字段上使用
@Autowired等注解注入。
- setter 注入:通过
- 示例:
public class UserService { private UserRepository userRepository; // 构造器注入 @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } }
4. 初始化前处理(Post Process Before Initialization)
- 阶段说明:在 Bean 初始化前,执行
BeanPostProcessor的postProcessBeforeInitialization方法。 - 作用:可用于修改 Bean 的属性值,或在初始化前对 Bean 进行增强(如 AOP 代理生成)。
- 示例:
public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { if (bean instanceof UserService) { System.out.println("初始化前处理:" + beanName); } return bean; } }
5. 初始化(Initialization)
- 阶段说明:调用 Bean 的初始化方法,完成资源加载、配置初始化等操作。
- 初始化方式:
- 实现
InitializingBean接口:重写afterPropertiesSet()方法。 - 使用
@PostConstruct注解:标注在方法上(JSR-250 规范)。 - 在 XML 中配置
init-method:指定初始化方法名。
- 实现
- 示例:
执行顺序:public class UserService implements InitializingBean { @PostConstruct public void init1() { System.out.println("@PostConstruct 初始化"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean 初始化"); } public void init2() { System.out.println("init-method 初始化"); } }@PostConstruct>InitializingBean.afterPropertiesSet()>init-method。
6. 初始化后处理(Post Process After Initialization)
- 阶段说明:在 Bean 初始化后,执行
BeanPostProcessor的postProcessAfterInitialization方法。 - 作用:常用于完成 AOP 代理的最终包装,或对 Bean 进行最后的增强处理。
- 示例:
public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) { if (bean instanceof UserService) { System.out.println("初始化后处理:" + beanName); } return bean; } }
7. Bean 就绪(Ready for Use)
- 阶段说明:Bean 已完全初始化,可被容器中的其他组件调用。
- 应用场景:如 Web 层调用 Service 层 Bean,Service 层调用 Repository 层 Bean 等。
8. 销毁前处理(Pre-Destruction)
- 阶段说明:当容器关闭时,在 Bean 销毁前执行相关操作。
- 销毁方式:
- 实现
DisposableBean接口:重写destroy()方法。 - 使用
@PreDestroy注解:标注在方法上(JSR-250 规范)。 - 在 XML 中配置
destroy-method:指定销毁方法名。
- 实现
- 示例:
执行顺序:public class UserService implements DisposableBean { @PreDestroy public void destroy1() { System.out.println("@PreDestroy 销毁前处理"); } @Override public void destroy() throws Exception { System.out.println("DisposableBean 销毁"); } public void destroy2() { System.out.println("destroy-method 销毁"); } }@PreDestroy>DisposableBean.destroy()>destroy-method。
9. 销毁(Destruction)
- 阶段说明:Bean 被销毁,释放占用的资源(如数据库连接、文件句柄等)。
- 触发时机:
- 手动关闭容器(如
context.close())。 - 应用程序正常退出或异常终止。
- 手动关闭容器(如
二、Bean 生命周期关键接口与注解总结
| 阶段 | 接口/注解 | 示例方法 | 执行时机 |
|---|---|---|---|
| 初始化前 | BeanPostProcessor | postProcessBeforeInitialization | Bean 初始化前 |
| 初始化 | InitializingBean | afterPropertiesSet | 属性填充后,初始化方法前 |
| 初始化 | @PostConstruct | 自定义方法 | 属性填充后,InitializingBean 前 |
| 初始化 | init-method | 自定义方法 | InitializingBean 后 |
| 初始化后 | BeanPostProcessor | postProcessAfterInitialization | 初始化方法后 |
| 销毁前 | DisposableBean | destroy | 容器关闭时,销毁方法前 |
| 销毁前 | @PreDestroy | 自定义方法 | DisposableBean 前 |
| 销毁前 | destroy-method | 自定义方法 | DisposableBean 后 |
三、Bean 生命周期流程图
容器启动,加载Bean定义 --------------------→
↓
实例化Bean(通过构造函数或工厂方法)------→
↓
填充Bean属性(依赖注入)------------------→
↓
调用BeanPostProcessor.postProcessBeforeInitialization →
↓
调用初始化方法(@PostConstruct/InitializingBean/init-method)→
↓
调用BeanPostProcessor.postProcessAfterInitialization →
↓
Bean就绪,可被使用 ----------------------→
↓
容器关闭时,调用@PreDestroy/DisposableBean/destroy-method →
↓
Bean销毁,释放资源 ----------------------→
四、典型应用场景
-
资源初始化与释放:
- 在初始化方法中连接数据库、加载配置文件。
- 在销毁方法中关闭数据库连接、释放线程池资源。
-
AOP 代理生成:
BeanPostProcessor在初始化后处理阶段生成代理对象(如AnnotationAwareAspectJAutoProxyCreator)。
-
动态属性修改:
- 通过
BeanPostProcessor在初始化前后修改 Bean 的属性值(如加密配置项)。
- 通过
五、注意事项
- 单例与原型 Bean 的区别:
- 单例 Bean:生命周期与容器一致,容器关闭时销毁。
- 原型 Bean:每次获取时创建新实例,容器不管理其销毁(需手动释放资源)。
- 初始化与销毁方法的异常处理:
- 初始化方法抛出异常会导致容器启动失败。
- 销毁方法抛出异常会被日志记录,但不影响容器关闭。
- 注解与接口的优先级:
@PostConstruct和@PreDestroy优于接口实现(基于 JSR 规范,更通用)。
通过掌握 Bean 的生命周期,开发者可以更精准地控制 Bean 的行为,实现复杂的初始化逻辑和资源管理,提升 Spring 应用的健壮性和灵活性。

1万+

被折叠的 条评论
为什么被折叠?



