Spring 如何调用 Bean 的初始化方法和销毁方法?

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. 实现 InitializingBeanDisposableBean 接口 (Spring 接口):

  • InitializingBean:

    • 包含一个 afterPropertiesSet 方法。
    • Spring 容器会在 Bean 的所有属性设置完成后、@PostConstruct 方法之后,调用 afterPropertiesSet 方法。
  • DisposableBean:

    • 包含一个 destroy 方法。
    • Spring 容器会在 Bean 被销毁之前、@PreDestroy 方法之后,调用 destroy 方法。
  • 优点:

    • 明确: 通过接口明确了 Bean 的初始化和销毁行为。
  • 缺点:

    • 与 Spring 框架耦合: InitializingBeanDisposableBean 是 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-methoddestroy-method 属性 (XML 配置):

  • init-method:

    • 在 XML 配置文件的 <bean> 标签中,使用 init-method 属性指定 Bean 的初始化方法。
    • Spring 容器会在 Bean 的所有属性设置完成后、InitializingBean.afterPropertiesSet 方法之后,调用 init-method 指定的方法。
  • destroy-method:

    • 在 XML 配置文件的 <bean> 标签中,使用 destroy-method 属性指定 Bean 的销毁方法。
    • Spring 容器会在 Bean 被销毁之前、DisposableBean.destroy 方法之后,调用 destroy-method 指定的方法。
  • 优点:

    • 与 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 容器会按照以下顺序调用:

  • 初始化方法:

    1. @PostConstruct
    2. InitializingBean.afterPropertiesSet
    3. init-method
  • 销毁方法:

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

实践:

  • 优先使用 @PostConstruct@PreDestroy 注解: 它们是 JSR-250 标准注解,与 Spring 框架解耦,代码更简洁。
  • 避免过度使用 InitializingBeanDisposableBean 接口: 它们会将你的代码与 Spring 框架耦合。
  • 谨慎使用 init-methoddestroy-method 属性: 它们只能用于 XML 配置,并且存在类型不安全的问题。
  • 不要在同一个Bean中同时使用多种方式定义初始化/销毁方法。 这样做会使代码难以理解和维护。

总结:

Spring 提供了多种方式来指定和调用 Bean 的初始化方法和销毁方法,包括 @PostConstruct@PreDestroy 注解、InitializingBeanDisposableBean 接口,以及 init-methoddestroy-method 属性。 推荐优先使用 @PostConstruct@PreDestroy 注解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值