Spring 提供了三种主要方式来指定和调用 Bean 的初始化方法和销毁方法:
1. 使用 @PostConstruct 和 @PreDestroy 注解 (JSR-250 注解):
-
@PostConstruct:- 标注在方法上,表示该方法是 Bean 的初始化方法。
- Spring 容器会在 Bean 的所有属性设置完成后、
InitializingBean.afterPropertiesSet方法之前,调用@PostConstruct标注的方法。 - 一个 Bean 可以有多个
@PostConstruct方法,但它们的执行顺序是不确定的。
-
@PreDestroy:- 标注在方法上,表示该方法是 Bean 的销毁方法。
- Spring 容器会在 Bean 被销毁之前、
DisposableBean.destroy方法之前,调用@PreDestroy标注的方法。 - 一个 Bean 可以有多个
@PreDestroy方法,但它们的执行顺序是不确定的。
-
优点:
- 简洁: 使用注解,代码更简洁、更易读。
- 与 Spring 框架解耦:
@PostConstruct和@PreDestroy是 JSR-250 (Common Annotations for the Java Platform) 中的注解,不依赖于 Spring API。
-
缺点:
- 只能标注在方法上: 不能用于字段或其他地方。
- 需要 Common Annotations API: 如果你的项目没有包含此 API, 则需要单独引入. 现代 Java EE 和 Jakarta EE 环境通常已经包含了。
-
示例:
import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.stereotype.Component; @Component public class MyBean { @PostConstruct public void init() { System.out.println("MyBean 初始化 (@PostConstruct)"); } @PreDestroy public void cleanup() { System.out.println("MyBean 销毁 (@PreDestroy)"); } }
2. 实现 InitializingBean 和 DisposableBean 接口 (Spring 接口):
-
InitializingBean:- 包含一个
afterPropertiesSet方法。 - Spring 容器会在 Bean 的所有属性设置完成后、
@PostConstruct方法之后,调用afterPropertiesSet方法。
- 包含一个
-
DisposableBean:- 包含一个
destroy方法。 - Spring 容器会在 Bean 被销毁之前、
@PreDestroy方法之后,调用destroy方法。
- 包含一个
-
优点:
- 明确: 通过接口明确了 Bean 的初始化和销毁行为。
-
缺点:
- 与 Spring 框架耦合:
InitializingBean和DisposableBean是 Spring 框架的接口。 - 只能有一个初始化/销毁方法: 每个接口只能定义一个方法。
- 与 Spring 框架耦合:
-
示例:
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @Component public class MyBean implements InitializingBean, DisposableBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("MyBean 初始化 (InitializingBean.afterPropertiesSet)"); } @Override public void destroy() throws Exception { System.out.println("MyBean 销毁 (DisposableBean.destroy)"); } }
3. 使用 init-method 和 destroy-method 属性 (XML 配置):
-
init-method:- 在 XML 配置文件的
<bean>标签中,使用init-method属性指定 Bean 的初始化方法。 - Spring 容器会在 Bean 的所有属性设置完成后、
InitializingBean.afterPropertiesSet方法之后,调用init-method指定的方法。
- 在 XML 配置文件的
-
destroy-method:- 在 XML 配置文件的
<bean>标签中,使用destroy-method属性指定 Bean 的销毁方法。 - Spring 容器会在 Bean 被销毁之前、
DisposableBean.destroy方法之后,调用destroy-method指定的方法。
- 在 XML 配置文件的
-
优点:
- 与 Spring 框架解耦: 不需要实现 Spring 的接口或使用 Spring 的注解。
- 可以在 XML 配置中集中管理: 方便查看和修改 Bean 的初始化和销毁方法。
-
缺点:
- 只能用于 XML 配置: 不能用于注解配置或 Java 配置。
- 配置冗余: 需要在 XML 配置文件中指定方法名。
- 类型不安全: 如果方法名拼写错误,Spring 在运行时才会报错。
-
示例:
<bean id="myBean" class="com.example.MyBean" init-method="myInit" destroy-method="myCleanup"/>public class MyBean { public void myInit() { System.out.println("MyBean 初始化 (init-method)"); } public void myCleanup() { System.out.println("MyBean 销毁 (destroy-method)"); } }
调用顺序:
对于同一个 Bean,如果同时使用了多种方式指定初始化或销毁方法,Spring 容器会按照以下顺序调用:
-
初始化方法:
@PostConstructInitializingBean.afterPropertiesSetinit-method
-
销毁方法:
@PreDestroyDisposableBean.destroydestroy-method
实践:
- 优先使用
@PostConstruct和@PreDestroy注解: 它们是 JSR-250 标准注解,与 Spring 框架解耦,代码更简洁。 - 避免过度使用
InitializingBean和DisposableBean接口: 它们会将你的代码与 Spring 框架耦合。 - 谨慎使用
init-method和destroy-method属性: 它们只能用于 XML 配置,并且存在类型不安全的问题。 - 不要在同一个Bean中同时使用多种方式定义初始化/销毁方法。 这样做会使代码难以理解和维护。
总结:
Spring 提供了多种方式来指定和调用 Bean 的初始化方法和销毁方法,包括 @PostConstruct 和 @PreDestroy 注解、InitializingBean 和 DisposableBean 接口,以及 init-method 和 destroy-method 属性。 推荐优先使用 @PostConstruct 和 @PreDestroy 注解。

1197

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



