本篇文章小编给大家分享一下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()方法"); } } @Configuration public class ConfigTest { @Bean(initMethod = "initCarA",destroyMethod = "destroyCarA") public CarA carA(){ return new CarA(); } }
执行结果
CarA。。。构造函数
CarA的init()方法
服务启动
CarA的destroy()方法
2. 方法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()方法执行"); } } @Configuration public class ConfigTest { @Bean public CarB carB(){ return new CarB(); } }
执行结果
CarB。。。构造函数
CarB。。。afterPropertiesSet()方法执行
服务启动
CarB。。。destroy()方法执行
2.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; }
2.3 方法1 && 方法2
相同点:都是在 bean 属性初始化之后需要执行的初始化方法。
不同点
方法1:代码不与Spring耦合;执行效率较低(通过反射来执行initMethod 方法)
方法2:代码与Spring紧耦合;速度更快(将 bean 强制转换成 InitializingBean 接口类型,然后直接调用 afterPropertiesSet 方法)
说明:afterPropertiesSet 和 initMethod 可以同时存在,但是 afterPropertiesSet 方法是在 initMethod 方法之前执行的。
一个 bean 从创建到初始化的过程总结
通过构造器创建 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"); } } @Configuration public 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 @Service public @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{ 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 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注解来定制执行顺序,越小越优先执行。
忍者必须死34399账号登录版 最新版v1.0.138v2.0.72
下载勇者秘境oppo版 安卓版v1.0.5
下载忍者必须死3一加版 最新版v1.0.138v2.0.72
下载绝世仙王官方正版 最新安卓版v1.0.49
下载Goat Simulator 3手机版 安卓版v1.0.8.2
Goat Simulator 3手机版是一个非常有趣的模拟游
Goat Simulator 3国际服 安卓版v1.0.8.2
Goat Simulator 3国际版是一个非常有趣的山羊模
烟花燃放模拟器中文版 2025最新版v1.0
烟花燃放模拟器是款仿真的烟花绽放模拟器类型单机小游戏,全方位
我的世界动漫世界 手机版v友y整合
我的世界动漫世界模组整合包是一款加入了动漫元素的素材整合包,
我的世界贝爷生存整合包 最新版v隔壁老王
我的世界MITE贝爷生存整合包是一款根据原版MC制作的魔改整