InitializingBean 和 DisposableBean
这两个接口定义Bean的初始化和销毁回调。
接口定义
Java
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
public interface DisposableBean {
void destroy() throws Exception;
}
执行时机
初始化时机
Java
┌─────────────────────────────────────┐
│ Bean实例化 │
├─────────────────────────────────────┤
│ 属性注入 │
├─────────────────────────────────────┤
│ Aware接口回调 │
├─────────────────────────────────────┤
│ BeanPostProcessor前置处理 │
├─────────────────────────────────────┤
│ @PostConstruct │ ← 先执行
├─────────────────────────────────────┤
│ InitializingBean.afterPropertiesSet │ ← 后执行
├─────────────────────────────────────┤
│ BeanPostProcessor后置处理 │
└─────────────────────────────────────┘
销毁时机
Java
┌─────────────────────────────────────┐
│ 容器关闭 │
├─────────────────────────────────────┤
│ @PreDestroy │ ← 先执行
├─────────────────────────────────────┤
│ DisposableBean.destroy │ ← 后执行
├─────────────────────────────────────┤
│ 自定义destroy-method │
└─────────────────────────────────────┘
实现示例
XML
@Component
public class DatabaseConnection implements InitializingBean, DisposableBean {
private Connection connection;
private String url;
private String username;
@Override
public void afterPropertiesSet() throws Exception {
// 属性注入完成后初始化
connection = DriverManager.getConnection(url, username, password);
System.out.println("数据库连接初始化完成");
}
@Override
public void destroy() throws Exception {
// Bean销毁时清理
if (connection != null && !connection.isClosed()) {
connection.close();
System.out.println("数据库连接已关闭");
}
}
}
与注解方式对比
Java
@Component
public class LifecycleBean implements InitializingBean, DisposableBean {
@PostConstruct // 先于afterPropertiesSet
public void initAnnotation() {
System.out.println("@PostConstruct执行");
}
@Override
public void afterPropertiesSet() {
System.out.println("afterPropertiesSet执行");
}
@PreDestroy // 先于destroy
public void destroyAnnotation() {
System.out.println("@PreDestroy执行");
}
@Override
public void destroy() {
System.out.println("destroy执行");
}
}
// 执行顺序:
// 初始化: @PostConstruct → afterPropertiesSet
// 销毁: @PreDestroy → destroy
| 方式 | 执行顺序 | 特点 |
|---|---|---|
| @PostConstruct | 第一 | JSR-250标准,推荐使用 |
| InitializingBean | 第二 | Spring接口,耦合容器 |
| @PreDestroy | 第一 | JSR-250标准,推荐使用 |
| DisposableBean | 第二 | Spring接口,耦合容器 |
推荐使用注解方式,减少对Spring接口的依赖。
XML配置init-method/destroy-method
Java
<bean id="myBean" class="com.example.MyBean"
init-method="customInit"
destroy-method="customDestroy"/>
Java
public class MyBean {
public void customInit() {
System.out.println("自定义初始化方法");
}
public void customDestroy() {
System.out.println("自定义销毁方法");
}
}
// 执行顺序:
// 初始化: @PostConstruct → afterPropertiesSet → customInit
// 销毁: @PreDestroy → destroy → customDestroy
三种方式组合执行顺序
text
初始化顺序:
1. @PostConstruct
2. InitializingBean.afterPropertiesSet
3. XML/init-method
销毁顺序:
1. @PreDestroy
2. DisposableBean.destroy
3. XML/destroy-method
实际应用场景
缓存初始化
text
@Component
public class CacheManager implements InitializingBean, DisposableBean {
private Map<String, Object> cache;
private ScheduledExecutorService scheduler;
@Override
public void afterPropertiesSet() {
cache = new ConcurrentHashMap<>();
scheduler = Executors.newScheduledThreadPool(1);
// 启动定时清理任务
scheduler.scheduleAtFixedRate(this::evictExpired, 1, 1, TimeUnit.HOURS);
}
@Override
public void destroy() {
scheduler.shutdown();
cache.clear();
}
private void evictExpired() {
// 清理过期缓存
}
}
连接池管理
text
@Component
public class ConnectionPool implements InitializingBean, DisposableBean {
private List<Connection> connections;
private int poolSize = 10;
@Override
public void afterPropertiesSet() throws Exception {
connections = new ArrayList<>(poolSize);
for (int i = 0; i < poolSize; i++) {
connections.add(createConnection());
}
}
@Override
public void destroy() throws Exception {
for (Connection conn : connections) {
conn.close();
}
connections.clear();
}
}
要点总结
- InitializingBean在属性注入后、@PostConstruct后执行
- DisposableBean在@PreDestroy后执行
- @PostConstruct/@PreDestroy优先于接口方法
- 推荐使用注解,减少Spring接口耦合
- 三种方式可组合使用,按固定顺序执行
📝 发现内容有误?点击此处直接编辑