当前位置: 首页 > news >正文

SSM从入门到实战:1.4 Spring Bean的生命周期管理

👋 大家好,我是 阿问学长!专注于分享优质开源项目解析、毕业设计项目指导支持、幼小初高教辅资料推荐等,欢迎关注交流!🚀

04-Spring Bean的生命周期管理

📖 本文概述

本文是SSM框架系列Spring进阶篇的第一篇,将深入探讨Spring Bean的完整生命周期。通过详细的代码示例和流程分析,帮助读者全面理解Bean从创建到销毁的整个过程,以及如何在各个阶段进行自定义处理。

🎯 学习目标

  • 深入理解Spring Bean的完整生命周期
  • 掌握Bean生命周期各个阶段的回调机制
  • 学会使用各种初始化和销毁方法
  • 了解BeanPostProcessor的作用和使用
  • 掌握Bean作用域对生命周期的影响

1. Bean生命周期概述

1.1 完整的生命周期流程

/*** Spring Bean生命周期完整流程演示*/
public class BeanLifecycleDemo {/*** Bean生命周期的主要阶段:* * 1. 实例化(Instantiation)*    - 通过构造器创建Bean实例* * 2. 属性填充(Population)*    - 设置Bean的属性值* * 3. 初始化(Initialization)*    - 执行各种初始化回调* * 4. 使用(In Use)*    - Bean可以被应用程序使用* * 5. 销毁(Destruction)*    - 容器关闭时销毁Bean*//*** 详细的生命周期步骤:* * 1. Bean实例化* 2. 设置Bean属性* 3. 调用BeanNameAware.setBeanName()* 4. 调用BeanFactoryAware.setBeanFactory()* 5. 调用ApplicationContextAware.setApplicationContext()* 6. 调用BeanPostProcessor.postProcessBeforeInitialization()* 7. 调用@PostConstruct注解的方法* 8. 调用InitializingBean.afterPropertiesSet()* 9. 调用自定义的init-method* 10. 调用BeanPostProcessor.postProcessAfterInitialization()* 11. Bean可以使用了* 12. 调用@PreDestroy注解的方法* 13. 调用DisposableBean.destroy()* 14. 调用自定义的destroy-method*/
}

1.2 生命周期演示Bean

/*** 完整的Bean生命周期演示*/
@Component
public class LifecycleDemoBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {private static final Logger logger = LoggerFactory.getLogger(LifecycleDemoBean.class);private String name;private String value;/*** 1. 构造器 - Bean实例化*/public LifecycleDemoBean() {logger.info("1. 构造器调用 - Bean实例化");}/*** 2. 属性设置*/public void setName(String name) {logger.info("2. 设置属性 name = {}", name);this.name = name;}public void setValue(String value) {logger.info("2. 设置属性 value = {}", value);this.value = value;}/*** 3. BeanNameAware接口回调*/@Overridepublic void setBeanName(String beanName) {logger.info("3. BeanNameAware.setBeanName() - beanName = {}", beanName);}/*** 4. BeanFactoryAware接口回调*/@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {logger.info("4. BeanFactoryAware.setBeanFactory() - beanFactory = {}", beanFactory.getClass().getSimpleName());}/*** 5. ApplicationContextAware接口回调*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {logger.info("5. ApplicationContextAware.setApplicationContext() - applicationContext = {}", applicationContext.getClass().getSimpleName());}/*** 7. @PostConstruct注解的初始化方法*/@PostConstructpublic void postConstruct() {logger.info("7. @PostConstruct注解方法调用");}/*** 8. InitializingBean接口回调*/@Overridepublic void afterPropertiesSet() throws Exception {logger.info("8. InitializingBean.afterPropertiesSet()");}/*** 9. 自定义初始化方法*/public void customInit() {logger.info("9. 自定义初始化方法 customInit()");}/*** 业务方法*/public void doSomething() {logger.info("11. Bean正在使用中 - doSomething()");}/*** 12. @PreDestroy注解的销毁方法*/@PreDestroypublic void preDestroy() {logger.info("12. @PreDestroy注解方法调用");}/*** 13. DisposableBean接口回调*/@Overridepublic void destroy() throws Exception {logger.info("13. DisposableBean.destroy()");}/*** 14. 自定义销毁方法*/public void customDestroy() {logger.info("14. 自定义销毁方法 customDestroy()");}
}

1.3 配置生命周期回调

/*** Bean生命周期配置*/
@Configuration
public class LifecycleConfig {/*** 使用@Bean注解配置初始化和销毁方法*/@Bean(initMethod = "customInit", destroyMethod = "customDestroy")public LifecycleDemoBean lifecycleDemoBean() {LifecycleDemoBean bean = new LifecycleDemoBean();bean.setName("Demo Bean");bean.setValue("Demo Value");return bean;}/*** 配置全局的初始化和销毁方法*/@Beanpublic static BeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}
}/*** XML配置方式*/
/*
<bean id="lifecycleDemoBean" class="com.example.bean.LifecycleDemoBean"init-method="customInit" destroy-method="customDestroy"><property name="name" value="Demo Bean"/><property name="value" value="Demo Value"/>
</bean><!-- 全局默认初始化和销毁方法 -->
<beans default-init-method="init" default-destroy-method="cleanup"><!-- Bean定义 -->
</beans>
*/

2. BeanPostProcessor详解

2.1 自定义BeanPostProcessor

/*** 自定义BeanPostProcessor演示*/
@Component
public class LifecycleBeanPostProcessor implements BeanPostProcessor {private static final Logger logger = LoggerFactory.getLogger(LifecycleBeanPostProcessor.class);/*** 6. 初始化前处理*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof LifecycleDemoBean) {logger.info("6. BeanPostProcessor.postProcessBeforeInitialization() - beanName = {}", beanName);}return bean;}/*** 10. 初始化后处理*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof LifecycleDemoBean) {logger.info("10. BeanPostProcessor.postProcessAfterInitialization() - beanName = {}", beanName);}return bean;}
}/*** 功能性BeanPostProcessor示例*/
@Component
public class ValidationBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// 在初始化前进行验证validateBean(bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// 在初始化后进行代理或增强return enhanceBean(bean, beanName);}private void validateBean(Object bean) {// 验证Bean的配置if (bean instanceof Validatable) {((Validatable) bean).validate();}}private Object enhanceBean(Object bean, String beanName) {// 可以在这里创建代理对象if (needsEnhancement(bean)) {return createProxy(bean);}return bean;}private boolean needsEnhancement(Object bean) {// 判断是否需要增强return bean.getClass().isAnnotationPresent(Enhance.class);}private Object createProxy(Object bean) {// 创建代理对象return bean; // 简化实现}
}/*** 验证接口*/
public interface Validatable {void validate();
}/*** 增强注解*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Enhance {
}

2.2 InstantiationAwareBeanPostProcessor

/*** InstantiationAwareBeanPostProcessor演示*/
@Component
public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {private static final Logger logger = LoggerFactory.getLogger(CustomInstantiationAwareBeanPostProcessor.class);/*** 实例化前回调*/@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {if (LifecycleDemoBean.class.equals(beanClass)) {logger.info("0. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()");// 可以返回一个代理对象来替代默认的实例化过程// return createCustomInstance(beanClass);}return null; // 返回null表示使用默认的实例化过程}/*** 实例化后回调*/@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {if (bean instanceof LifecycleDemoBean) {logger.info("1.5. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()");}return true; // 返回true表示继续属性填充,false表示跳过属性填充}/*** 属性值处理*/@Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {if (bean instanceof LifecycleDemoBean) {logger.info("2.5. InstantiationAwareBeanPostProcessor.postProcessProperties()");// 可以修改属性值MutablePropertyValues mpvs = new MutablePropertyValues(pvs);mpvs.add("value", "Modified by InstantiationAwareBeanPostProcessor");return mpvs;}return pvs;}
}

3. 初始化和销毁方法

3.1 多种初始化方式的优先级

/*** 初始化方法优先级演示*/
@Component
public class InitializationOrderBean implements InitializingBean {private static final Logger logger = LoggerFactory.getLogger(InitializationOrderBean.class);/*** 优先级1:@PostConstruct注解(最高优先级)*/@PostConstructpublic void postConstructMethod() {logger.info("1. @PostConstruct方法执行");}/*** 优先级2:InitializingBean.afterPropertiesSet()*/@Overridepublic void afterPropertiesSet() throws Exception {logger.info("2. InitializingBean.afterPropertiesSet()执行");}/*** 优先级3:自定义初始化方法(最低优先级)*/public void customInitMethod() {logger.info("3. 自定义初始化方法执行");}
}/*** 配置初始化方法*/
@Configuration
public class InitializationConfig {@Bean(initMethod = "customInitMethod")public InitializationOrderBean initializationOrderBean() {return new InitializationOrderBean();}
}

3.2 条件初始化

/*** 条件初始化示例*/
@Component
public class ConditionalInitializationBean {@Value("${app.feature.enabled:false}")private boolean featureEnabled;@Value("${app.environment:dev}")private String environment;private FeatureService featureService;@PostConstructpublic void init() {if (featureEnabled) {initializeFeature();}if ("production".equals(environment)) {initializeProductionSettings();}}private void initializeFeature() {this.featureService = new FeatureServiceImpl();logger.info("功能服务已初始化");}private void initializeProductionSettings() {// 生产环境特定的初始化logger.info("生产环境设置已初始化");}@PreDestroypublic void cleanup() {if (featureService != null) {featureService.shutdown();logger.info("功能服务已关闭");}}
}

3.3 异步初始化

/*** 异步初始化示例*/
@Component
public class AsyncInitializationBean {private static final Logger logger = LoggerFactory.getLogger(AsyncInitializationBean.class);@Autowiredprivate TaskExecutor taskExecutor;private volatile boolean initialized = false;private CountDownLatch initializationLatch = new CountDownLatch(1);@PostConstructpublic void init() {logger.info("开始异步初始化");taskExecutor.execute(() -> {try {// 模拟耗时的初始化操作Thread.sleep(5000);// 执行实际的初始化逻辑performHeavyInitialization();initialized = true;initializationLatch.countDown();logger.info("异步初始化完成");} catch (Exception e) {logger.error("异步初始化失败", e);}});}private void performHeavyInitialization() {// 耗时的初始化操作// 例如:加载大量数据、建立网络连接等}public void doSomething() throws InterruptedException {// 等待初始化完成if (!initialized) {logger.info("等待初始化完成...");initializationLatch.await();}// 执行业务逻辑logger.info("执行业务逻辑");}@PreDestroypublic void destroy() {logger.info("Bean销毁");}
}

4. Bean作用域与生命周期

4.1 不同作用域的生命周期

/*** 不同作用域的Bean生命周期演示*/
@Configuration
public class ScopeLifecycleConfig {/*** 单例Bean - 容器启动时创建,容器关闭时销毁*/@Bean@Scope("singleton")public SingletonBean singletonBean() {return new SingletonBean();}/*** 原型Bean - 每次获取时创建,不由容器管理销毁*/@Bean@Scope("prototype")public PrototypeBean prototypeBean() {return new PrototypeBean();}/*** 请求作用域Bean - 每个HTTP请求创建一个实例*/@Bean@Scope("request")public RequestScopedBean requestScopedBean() {return new RequestScopedBean();}/*** 会话作用域Bean - 每个HTTP会话创建一个实例*/@Bean@Scope("session")public SessionScopedBean sessionScopedBean() {return new SessionScopedBean();}
}/*** 单例Bean*/
public class SingletonBean implements DisposableBean {private static final Logger logger = LoggerFactory.getLogger(SingletonBean.class);public SingletonBean() {logger.info("SingletonBean创建");}@PostConstructpublic void init() {logger.info("SingletonBean初始化");}@Overridepublic void destroy() throws Exception {logger.info("SingletonBean销毁");}
}/*** 原型Bean*/
public class PrototypeBean implements DisposableBean {private static final Logger logger = LoggerFactory.getLogger(PrototypeBean.class);public PrototypeBean() {logger.info("PrototypeBean创建 - {}", this.hashCode());}@PostConstructpublic void init() {logger.info("PrototypeBean初始化 - {}", this.hashCode());}@Overridepublic void destroy() throws Exception {// 注意:原型Bean的destroy方法不会被自动调用logger.info("PrototypeBean销毁 - {}", this.hashCode());}
}

4.2 原型Bean的销毁管理

/*** 原型Bean销毁管理*/
@Component
public class PrototypeBeanManager implements DisposableBean {private static final Logger logger = LoggerFactory.getLogger(PrototypeBeanManager.class);@Autowiredprivate ApplicationContext applicationContext;private final Set<PrototypeBean> prototypeBeans = ConcurrentHashMap.newKeySet();/*** 获取原型Bean并注册到管理器*/public PrototypeBean getPrototypeBean() {PrototypeBean bean = applicationContext.getBean(PrototypeBean.class);prototypeBeans.add(bean);logger.info("原型Bean已注册到管理器: {}", bean.hashCode());return bean;}/*** 手动销毁原型Bean*/public void destroyPrototypeBean(PrototypeBean bean) {if (prototypeBeans.remove(bean)) {try {bean.destroy();logger.info("原型Bean已手动销毁: {}", bean.hashCode());} catch (Exception e) {logger.error("销毁原型Bean失败", e);}}}/*** 容器关闭时销毁所有原型Bean*/@Overridepublic void destroy() throws Exception {logger.info("开始销毁所有原型Bean,数量: {}", prototypeBeans.size());for (PrototypeBean bean : prototypeBeans) {try {bean.destroy();logger.info("原型Bean已销毁: {}", bean.hashCode());} catch (Exception e) {logger.error("销毁原型Bean失败: {}", bean.hashCode(), e);}}prototypeBeans.clear();}
}

5. 生命周期最佳实践

5.1 资源管理

/*** 资源管理最佳实践*/
@Component
public class ResourceManagementBean {private static final Logger logger = LoggerFactory.getLogger(ResourceManagementBean.class);private ExecutorService executorService;private Connection databaseConnection;private FileInputStream fileInputStream;@PostConstructpublic void initializeResources() {try {// 初始化线程池executorService = Executors.newFixedThreadPool(10);logger.info("线程池已初始化");// 初始化数据库连接databaseConnection = createDatabaseConnection();logger.info("数据库连接已建立");// 初始化文件流fileInputStream = new FileInputStream("config.properties");logger.info("文件流已打开");} catch (Exception e) {logger.error("资源初始化失败", e);// 清理已创建的资源cleanupResources();throw new RuntimeException("资源初始化失败", e);}}@PreDestroypublic void cleanupResources() {logger.info("开始清理资源");// 关闭线程池if (executorService != null && !executorService.isShutdown()) {executorService.shutdown();try {if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {executorService.shutdownNow();}logger.info("线程池已关闭");} catch (InterruptedException e) {executorService.shutdownNow();Thread.currentThread().interrupt();}}// 关闭数据库连接if (databaseConnection != null) {try {databaseConnection.close();logger.info("数据库连接已关闭");} catch (SQLException e) {logger.error("关闭数据库连接失败", e);}}// 关闭文件流if (fileInputStream != null) {try {fileInputStream.close();logger.info("文件流已关闭");} catch (IOException e) {logger.error("关闭文件流失败", e);}}}private Connection createDatabaseConnection() throws SQLException {// 创建数据库连接的逻辑return DriverManager.getConnection("jdbc:h2:mem:testdb", "sa", "");}
}

5.2 优雅关闭

/*** 优雅关闭示例*/
@Component
public class GracefulShutdownBean implements ApplicationListener<ContextClosedEvent> {private static final Logger logger = LoggerFactory.getLogger(GracefulShutdownBean.class);private volatile boolean shutdownRequested = false;private final CountDownLatch shutdownLatch = new CountDownLatch(1);@EventListenerpublic void handleContextClosed(ContextClosedEvent event) {logger.info("接收到容器关闭事件,开始优雅关闭");shutdownRequested = true;// 等待正在进行的操作完成waitForOperationsToComplete();shutdownLatch.countDown();}private void waitForOperationsToComplete() {// 等待正在进行的操作完成int maxWaitTime = 30; // 最大等待30秒int waitTime = 0;while (hasOngoingOperations() && waitTime < maxWaitTime) {try {Thread.sleep(1000);waitTime++;logger.info("等待操作完成... {}s", waitTime);} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}}if (waitTime >= maxWaitTime) {logger.warn("等待超时,强制关闭");} else {logger.info("所有操作已完成,可以安全关闭");}}private boolean hasOngoingOperations() {// 检查是否有正在进行的操作return false; // 简化实现}public void performOperation() {if (shutdownRequested) {logger.warn("系统正在关闭,拒绝新的操作");return;}// 执行业务操作logger.info("执行业务操作");}@PreDestroypublic void destroy() {try {// 等待优雅关闭完成shutdownLatch.await(35, TimeUnit.SECONDS);logger.info("Bean销毁完成");} catch (InterruptedException e) {Thread.currentThread().interrupt();logger.error("等待优雅关闭被中断", e);}}
}

6. 小结

本文深入介绍了Spring Bean的生命周期管理:

  1. 生命周期流程:从实例化到销毁的完整过程
  2. 回调机制:各种Aware接口和初始化/销毁方法
  3. BeanPostProcessor:Bean处理器的作用和自定义实现
  4. 作用域影响:不同作用域对生命周期的影响
  5. 最佳实践:资源管理和优雅关闭的实现

掌握Bean生命周期的关键点:

  • 理解生命周期各个阶段的执行顺序
  • 合理选择初始化和销毁方法
  • 正确管理资源的创建和释放
  • 注意不同作用域的生命周期差异
  • 实现优雅的关闭机制

🔗 下一篇预告

下一篇文章将介绍Spring事务管理深入解析,学习如何使用Spring管理数据库事务。


相关文章:

  • 上一篇:面向切面编程原理与应用
  • 下一篇:Spring事务管理深入解析
  • 返回目录
http://www.lryc.cn/news/624704.html

相关文章:

  • 【STM32】STM32H750 CubeMX 配置 USB CDC 虚拟串口笔记
  • ThinkPHP的安装运行和调试
  • MCP协议演进:从SSE到Streamable HTTP的技术革命
  • SAP ABAP IS SUPPLIED
  • 【语法糖】什么是语法糖
  • Java+Vue构建资产设备管理系统,适配移动端与后台管理,实现全生命周期管理,涵盖采购、入库、使用、维护、报废等环节,提供完整源码,便于二次开发
  • 快速搭建项目(若依)
  • CentOS 7 LAMP快速部署WordPress指南
  • linux中的hostpath卷、nfs卷以及静态持久卷的区别
  • python+flask后端开发~项目实战 | 博客问答项目--数据库信息的基本配置与UserModel的创建,映射,关联
  • 【MySQL】超详细入门学习
  • Linux 系统(如 Ubuntu / CentOS)阿里云虚拟机(ECS)上部署 Bitnami LAMP
  • 【Python】Python Socket 网络编程详解:从基础到实践​
  • 云原生俱乐部-mysql知识点归纳(1)
  • 【前端面试题】JavaScript 核心知识点解析(第十四题解析到第二十二题)
  • 【牛客刷题】正六边形阴影面积计算
  • FastRTSP介绍
  • 微电网管控系统中python多线程缓存与SQLite多数据库文件连接池实践总结(含源码)
  • 多台服务器批量发布arcgisserver服务并缓存切片
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频内容理解与智能预警升级(401)
  • Python入门Day18:模块与包(module package)
  • Spring Boot + Spring Kafka 集成
  • SMTPman,smtp ssl助力安全高效邮件传输!
  • Java 中表示数据集的常用集合类
  • 低端设备加载webp ANR
  • 安全存储之 SAES+HUK 使用技巧和常见问题 LAT1543
  • Rust 教程之简介000
  • CSS:水平垂直居中
  • 【银河麒麟桌面系统】配置匿名文件夹与用户认证共享服务
  • 2025年秋招Java后端面试场景题+八股文题目