文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Bean自定义初始化和销毁方法是什么

2023-06-29 01:20

关注

今天小编给大家分享一下Bean自定义初始化和销毁方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

Bean三种自定义初始化和销毁

一. 三种方法概述

在配置类中指定 @Bean(initMethod = “init”,destroyMethod = “destory”)注解

实现InitializingBean接口并重写其afterPropertiesSet方法,实现DisposableBean接口并重写destroy方法

利用java的JSR250规范中的@PostConstruct标注在init方法上,@PreDestroy标注在destroy方法上

二. 方法详述

1. 方法1:配置类中指定

示例代码

public class CarA {    public CarA() {        System.out.println("CarA。。。构造函数");    }    public void initCarA(){        System.out.println("CarA的init()方法");    }    public void destroyCarA(){        System.out.println("CarA的destroy()方法");    }}@Configurationpublic class ConfigTest {    @Bean(initMethod = "initCarA",destroyMethod = "destroyCarA")    public CarA carA(){        return new CarA();    }}

执行结果

CarA。。。构造函数
CarA的init()方法

服务启动

CarA的destroy()方法

2. 方法2:实现接口并重写方法

1 示例代码

public class CarB implements InitializingBean, DisposableBean {    public CarB() {        System.out.println("CarB。。。构造函数");    }    @Override    public void afterPropertiesSet() throws Exception {        System.out.println("CarB。。。afterPropertiesSet()方法执行");    }    @Override    public void destroy() throws Exception {        System.out.println("CarB。。。destroy()方法执行");    }}@Configurationpublic class ConfigTest {    @Bean    public CarB carB(){        return new CarB();    }}

执行结果

CarB。。。构造函数
CarB。。。afterPropertiesSet()方法执行

服务启动

CarB。。。destroy()方法执行

2 概述

Spring 开放了扩展接口,允许我们自定义 bean 的初始化和销毁方法。即当 Spring 容器在 bean 进行到相应的生命周期阶段时,会自动调用我们自定义的初始化和销毁方法。这两个扩展接口是 InitializingBean 和 DisposableBean 。

InitializingBean 接口说明:该接口为 bean 提供了 bean 属性初始化后的处理方法,它只有 afterPropertiesSet 一个方法,凡是实现此接口的类,在 bean 的属性初始化后都会执行该方法。
package org.springframework.beans.factory;

public interface InitializingBean {    void afterPropertiesSet() throws Exception;}

DisposableBean 接口说明:该接口为单例 bean 提供了在容器销毁 bean 时的处理方法,它只有 destroy 一个方法,凡是实现此接口的类,在 bean 被销毁时都会执行该方法。

package org.springframework.beans.factory;public interface DisposableBean {    void destroy() throws Exception;}

3 方法1 && 方法2

方法1:代码不与Spring耦合;执行效率较低(通过反射来执行initMethod 方法)

方法2:代码与Spring紧耦合;速度更快(将 bean 强制转换成 InitializingBean 接口类型,然后直接调用 afterPropertiesSet 方法)

通过构造器创建 bean

属性注入

执行 afterPropertiesSet 方法

执行 initMethod 方法

3. 方法3:利用java的JSR250规范

代码示例

public class CarC {    public CarC() {        System.out.println("CarC。。。构造函数");    }    @PostConstruct    public void initCarC(){        System.out.println("CarC。。。初始化方法initCarC()");    }    @PreDestroy    public void destroyCarC(){        System.out.println("CarC。。。销毁方法destroyCarC");    }}@Configurationpublic class ConfigTest {    @Bean    public CarC carC(){        return new CarC();    }}

执行结果

CarC。。。构造函数
CarC。。。初始化方法initCarC()

服务启动

CarC。。。销毁方法destroyCarC

spring初始化后获取自定义注解Bean

目的是通过注解将特定类的信息(如接口编号)与类关联,之后可通过接口编号获取对应bean来执行对应逻辑。

一.新建注解类

@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Servicepublic @interface ServiceCode {    String code() default "";     String className() default "";}

包含接口编号和beanName信息。

二.新建接口类

@ServiceCode(code = "100010", className = "echoService")@Service("echoService")public class EchoService { }

三.实现接口ApplicationListener

来监听spring容器初始化完成后执行:

@Component@Order(1)public class ServiceInitListener implements ApplicationListener<ContextRefreshedEvent> {    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceInitListener.class);     @Override    public void onApplicationEvent(ContextRefreshedEvent event) {        ApplicationContext applicationContext = event.getApplicationContext();        //注意 需要时根容器才能通过注解获取到bean,比如event直接获取的容器中只有一些公共注册bean        if (applicationContext.getParent() != null) {            applicationContext = applicationContext.getParent();        }        Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(ServiceCode.class);        for (Object bean : beansWithAnnotation.values()) {            ServiceCode annotation = bean.getClass().getAnnotation(ServiceCode.class);            String code = annotation.code();            String className = annotation.className();            //注册接口编号和beanName            //在统一入口可通过code获取beanName,然后通过springContext获取对应bean执行自定义逻辑            //或者完成其他逻辑        }    } }

注意:

 ContextRefreshedEvent获取到的上下文环境不是根spring容器,其中只有部分spring内置bean,无法通过注解获取到自定义bean,需要获取其父容器来完成操作。我第一次获取是beanList总为空,后来发现其容器内部bean没有自定义的service bean,获取父容器后操作一切正常。

通过@Order注解来定制执行顺序,越小越优先执行。

以上就是“Bean自定义初始化和销毁方法是什么”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯