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

Spring Bean 生命周期详解:初始化与销毁方式对比与实践

目录

  • 一、Spring Bean 生命周期解析
    • 1、Bean 初始化方式
      • 1.1 @PostConstruct
      • 1.2 InitializingBean
      • 1.3 init-method
    • 2、Bean 销毁方式
      • 2.1 @PreDestroy
      • 2.2 DisposableBean
      • 2.3 destroy-method
    • 3、执行顺序对比
    • 4、实战案例(完整生命周期)
    • 5、总结
  • 二、现实开发中的使用场景
    • 1、初始化三兄弟
    • 2、销毁三兄弟
  • 三、总结对比(开发实践)

一、Spring Bean 生命周期解析

在 Spring 应用中,Bean 的生命周期主要分为两个关键阶段:

  • 初始化(Initialization)
  • 销毁(Destruction)

Spring 提供了多种方式来自定义这两个阶段的逻辑,主要包括:

  • 初始化:@PostConstructInitializingBeaninit-method
  • 销毁:@PreDestroyDisposableBeandestroy-method

1、Bean 初始化方式

1.1 @PostConstruct

  • JSR-250 标准注解
  • 方法要求:public void、无参
  • 推荐方式,最简洁
@Service
public class OrderService {@PostConstructpublic void init() {System.out.println("OrderService 初始化逻辑执行...");}
}

1.2 InitializingBean

  • 实现 Spring 提供的 InitializingBean 接口
  • 必须实现 afterPropertiesSet() 方法
  • 强耦合:类依赖 Spring
@Component
public class ProductService implements InitializingBean {@Overridepublic void afterPropertiesSet() {System.out.println("ProductService 初始化逻辑执行...");}
}

1.3 init-method

  • @Bean 或 XML 中配置
  • 方法名随意,但必须配置
  • 解耦:类本身不依赖 Spring
public class UserService {public void customInit() {System.out.println("UserService 初始化逻辑执行...");}
}@Configuration
public class AppConfig {@Bean(initMethod = "customInit")public UserService userService() {return new UserService();}
}

2、Bean 销毁方式

2.1 @PreDestroy

  • JSR-250 标准注解
  • 方法必须是 void、无参
  • 常与 @PostConstruct 配合使用
@Service
public class OrderService {@PreDestroypublic void destroy() {System.out.println("OrderService 销毁逻辑执行...");}
}

2.2 DisposableBean

  • 实现 Spring 提供的 DisposableBean 接口
  • 必须实现 destroy() 方法
  • 强耦合,但语义清晰
@Component
public class ProductService implements DisposableBean {@Overridepublic void destroy() {System.out.println("ProductService 销毁逻辑执行...");}
}

2.3 destroy-method

  • @Bean 或 XML 中配置
  • 方法名随意,但必须配置
public class UserService {public void customDestroy() {System.out.println("UserService 销毁逻辑执行...");}
}@Configuration
public class AppConfig {@Bean(destroyMethod = "customDestroy")public UserService userService() {return new UserService();}
}

3、执行顺序对比

假设一个 Bean 同时实现了三种方式,执行顺序如下:

初始化顺序:

  1. @PostConstruct
  2. InitializingBean.afterPropertiesSet()
  3. init-method

销毁顺序:

  1. @PreDestroy
  2. DisposableBean.destroy()
  3. destroy-method

4、实战案例(完整生命周期)

public class DemoService implements InitializingBean, DisposableBean {@PostConstructpublic void postConstructInit() {System.out.println("@PostConstruct 初始化执行...");}@Overridepublic void afterPropertiesSet() {System.out.println("InitializingBean.afterPropertiesSet() 初始化执行...");}public void customInit() {System.out.println("init-method 初始化执行...");}@PreDestroypublic void preDestroy() {System.out.println("@PreDestroy 销毁执行...");}@Overridepublic void destroy() {System.out.println("DisposableBean.destroy() 销毁执行...");}public void customDestroy() {System.out.println("destroy-method 销毁执行...");}
}@Configuration
class DemoConfig {@Bean(initMethod = "customInit", destroyMethod = "customDestroy")public DemoService demoService() {return new DemoService();}
}

启动和关闭应用的输出结果:

@PostConstruct 初始化执行...
InitializingBean.afterPropertiesSet() 初始化执行...
init-method 初始化执行...@PreDestroy 销毁执行...
DisposableBean.destroy() 销毁执行...
destroy-method 销毁执行...

5、总结

初始化

  • 推荐 @PostConstruct:最常用、最简洁
  • init-method:解耦、灵活,适合第三方库或不想耦合 Spring 的场景
  • InitializingBean:适合需要明确表达“依赖 Spring 生命周期”的场景

销毁

  • 推荐 @PreDestroy:最直观、常用
  • destroy-method:解耦、灵活
  • DisposableBean:语义明确,适合对生命周期严格要求的场景

简要说明

  • 初始化三兄弟@PostConstructInitializingBeaninit-method
  • 销毁三兄弟@PreDestroyDisposableBeandestroy-method
  • 推荐:常用场景下 @PostConstruct + @PreDestroy 就足够,特殊情况再用其他方式。

二、现实开发中的使用场景

1、初始化三兄弟

  1. @PostConstruct —— 日常开发首选

典型场景:

  • 初始化缓存数据
  • 启动时加载配置
  • 注册监听器或定时任务
  • 建立外部服务连接(如 Redis、消息队列、ElasticSearch 客户端)

案例:

@Service
public class CacheService {private final RedisTemplate<String, Object> redisTemplate;public CacheService(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;}@PostConstructpublic void loadCache() {System.out.println("系统启动 -> 预热缓存数据...");// redisTemplate.opsForValue().set("key", "value");}
}

👉 大多数业务 Bean 的初始化逻辑都推荐用 @PostConstruct,简洁直观。


  1. InitializingBean —— 需要强烈依赖 Spring 生命周期语义时

典型场景:

  • 框架/中间件开发中,需要明确表明这个 Bean 必须依赖 Spring 生命周期
  • 类似组件内核逻辑,初始化必须在依赖注入完成后严格执行

案例:

@Component
public class MQConsumer implements InitializingBean {@Overridepublic void afterPropertiesSet() {System.out.println("依赖注入完成后 -> 启动 MQ 消费者线程...");}
}

👉 更多出现在 基础设施层Spring Starter 开发里。普通业务开发很少用。


  1. init-method —— 解耦第三方类

典型场景:

  • 第三方类无法改源码
  • 又想在 Bean 创建时执行特定初始化方法
  • 保证代码和 Spring 解耦

案例:

public class ExternalClient {public void connect() {System.out.println("连接外部系统...");}
}@Configuration
public class ClientConfig {@Bean(initMethod = "connect")public ExternalClient externalClient() {return new ExternalClient();}
}

👉 在实际开发中,init-method 特别适合 引入第三方 SDK老代码改造场景。


2、销毁三兄弟

  1. @PreDestroy —— 业务代码的首选

典型场景:

  • 释放资源(关闭线程池、关闭连接池)
  • 清理缓存数据
  • 注销注册中心服务

案例:

@Service
public class WorkerPoolService {private ExecutorService executor = Executors.newFixedThreadPool(4);@PreDestroypublic void shutdown() {System.out.println("应用关闭 -> 释放线程池资源");executor.shutdown();}
}

👉 大多数业务场景首选 @PreDestroy,语义清晰。


  1. DisposableBean —— 框架层使用

典型场景:

  • InitializingBean 一样,强调生命周期语义
  • 适合做 框架封装Spring Starter,便于 Spring 统一管理

案例:

@Component
public class MetricsCollector implements DisposableBean {@Overridepublic void destroy() {System.out.println("关闭应用 -> 上传剩余指标数据");}
}

👉 多见于框架底层,普通业务 Bean 很少直接用。


  1. destroy-method —— 第三方类资源释放

典型场景:

  • 依然是第三方类或旧代码改造
  • 无法修改源码,但要在 Spring 容器销毁时执行清理逻辑

案例:

public class ExternalClient {public void close() {System.out.println("断开外部系统连接...");}
}@Configuration
public class ClientConfig {@Bean(destroyMethod = "close")public ExternalClient externalClient() {return new ExternalClient();}
}

👉 在引入外部库(比如数据库驱动、消息客户端)的场景中很实用。


三、总结对比(开发实践)

阶段推荐首选使用场景替补方案使用场景
初始化@PostConstruct绝大多数业务逻辑初始化init-method第三方类、解耦 Spring
InitializingBean框架/中间件,强调生命周期语义--
销毁@PreDestroy日常业务资源释放destroy-method第三方类、老代码
DisposableBean框架封装、Starter 开发--

👉 现实开发建议:

  • 普通业务类 → 用 @PostConstruct + @PreDestroy
  • 第三方类/旧代码 → 用 init-method + destroy-method
  • 框架层/Starter 开发 → 用 InitializingBean + DisposableBean

http://www.dtcms.com/a/466454.html

相关文章:

  • 做交易网站什么开发语言网络工程师
  • DeviceNet 转 Modbus TCP 协议转换在 S7-1200 PLC化工反应釜中的应用
  • 网站建设公司网络服务学美工难吗
  • S29-昆仑触屏串口批量写应用
  • C# 委托(Delegate)
  • 企业单位网站建设内容需要什么saas电商建站系统
  • 【63】OpenCV C++实战篇——用C++实现的直线卡尺工具--自选找线方向(从左到右、从右到左、从上到下、从下到上)
  • 做网站你们用什么浏览器如何免费建立个人网站
  • 《金钱心理学》读后感
  • 临沂网站设计建设wordpress 下拉菜单设置
  • PyTorch Transformers| Azure
  • 2.c++面向对象(二)
  • 苍穹外卖-Apache ECharts与数据统计
  • 合肥企业建站系统wap网站浏览器
  • python进阶_Day4
  • 网站开发小图标大全wordpress显示当前位置
  • 江苏建设信息网站有时候打不开网站建设客户问题
  • .Net Core WebApi集成Swagger
  • 趣味学网工:IPv6是连接未来的数字基石(IPv6的技术地位、重要作用、市场行情、应用场景等)
  • Linux 基本入门
  • 用ClaudeCode完善我的项目
  • 开源系统网站爱游戏app下载官方网站
  • SPA路由回退机制解析:解决History模式下的404问题
  • 边界感知分治:基于扩散模型的无监督阴影去除方案
  • 传输介质的简介
  • TPS, MIS, DSS, ES考题
  • 网站建设服务非常好湖南岚鸿公司响应式网站模版
  • 我的网站被攻击了!
  • 新乡专业的网站建设公司网站模板 php
  • WPS编辑排版之我见