当前位置: 首页 > news >正文

SpringBoot:Bean生命周期自定义初始化和销毁

在这里插入图片描述

🏡浩泽学编程:个人主页

 🔥 推荐专栏:《深入浅出SpringBoot》《java项目分享》
              《RabbitMQ》《Spring》《SpringMVC》

🛸学无止境,不骄不躁,知行合一

文章目录

  • 前言
  • 一、@Bean注解指定初始化和销毁方法
  • 二、实现InitializingBean接口和DisposableBean接口
  • 三、@PostConstruct(初始化逻辑)和@PreDestroy(销毁逻辑)注解
  • 四、BeanPostProcessor接口
  • 总结


前言

上篇文章详细讲诉了Bean的生命周期和作用域,在生命周期中提到了如何自定义初始化Bean,可能很多人不知道如何自定义初始化,这里详细补充讲解一下:使用@Bean注解指定初始化和销毁方法、实现InitializingBean接口和DisposableBean接口自定义初始化和销毁、@PostConstruct(初始化逻辑)和@PreDestroy(销毁逻辑)注解、使用BeanPostProcessor接口。


一、@Bean注解指定初始化和销毁方法

  • 创建BeanTest类,自定义初始化方法和销毁方法。
  • 在@Bean注解的参数中指定BeanTest自定义的初始化和销毁方法:
  • 销毁方法只有在IOC容器关闭的时候才调用。

代码如下:

/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: dog* @Description: TODO描述* @Date: 2024/1/21 22:55*/
public class BeanTest {public BeanTest(){System.out.println("BeanTest被创建");}public void init(){System.out.println("BeanTest被初始化");}public void destory(){System.out.println("BeanTest被销毁");}
}
/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: MyConfig* @Description: TODO描述* @Date: 2024/1/21 22:59*/
@Configuration
@ComponentScan(("com.dragon.restart1"))
public class MyConfig {@Bean(initMethod = "init",destroyMethod = "destory")public BeanTest beanTest(){return new BeanTest();}
}
//测试代码
AnnotationConfigApplicationContext ct = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println("IoC容器创建完成");

在这里插入图片描述

  • 可以看到调用的是自定义的方法,这里解释一下,测试时,运行完代码块程序就结束了,所哟IoC容器就被关闭,所以调用了IoC销毁方法。同时可以看到初始化方法在对象创建完成后调用。
  • 当组件的作用域为单例时在容器启动时即创建对象,而当作用域为原型(PROTOTYPE)时在每次获取对象的时候才创建对象。并且当作用域为原型(PROTOTYPE)时,IOC容器只负责创建Bean但不会管理Bean,所以IOC容器不会调用销毁方法。

二、实现InitializingBean接口和DisposableBean接口

看一下两接口的方法:

public interface InitializingBean {/*** Invoked by the containing {@code BeanFactory} after it has set all bean properties* and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.* <p>This method allows the bean instance to perform validation of its overall* configuration and final initialization when all bean properties have been set.* @throws Exception in the event of misconfiguration (such as failure to set an* essential property) or if initialization fails for any other reason* Bean都装配完成后执行初始化*/void afterPropertiesSet() throws Exception;
}
====================================================================
public interface DisposableBean {/*** Invoked by the containing {@code BeanFactory} on destruction of a bean.* @throws Exception in case of shutdown errors. Exceptions will get logged* but not rethrown to allow other beans to release their resources as well.*/void destroy() throws Exception;}

代码如下:

/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: BeanTest1* @Description: TODO描述* @Date: 2024/1/21 23:25*/
public class BeanTest1 implements InitializingBean, DisposableBean {@Overridepublic void destroy() throws Exception {System.out.println("BeanTest1销毁");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("BeanTest1初始化");}public BeanTest1() {System.out.println("BeanTest1被创建");}
}
=========================@Configuration
@ComponentScan(("com.dragon.restart1"))
public class MyConfig {@Beanpublic BeanTest1 beanTest1(){return new BeanTest1();}
}

在这里插入图片描述

三、@PostConstruct(初始化逻辑)和@PreDestroy(销毁逻辑)注解

  • 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。
  • 被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
  • 被@PreDestroy修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。

代码如下:

/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: BeanTest2* @Description: TODO描述* @Date: 2024/1/21 23:32*/
public class BeanTest2 {public BeanTest2(){System.out.println("BeanTest2被创建");}@PostConstructpublic void init(){System.out.println("BeanTest2被初始化");}@PreDestroypublic void destory(){System.out.println("BeanTest2被销毁");}
}
========================
//
@Configuration
@ComponentScan(("com.dragon.restart1"))
public class MyConfig {@Beanpublic BeanTest2 beanTest2(){return new BeanTest2();}
}

在这里插入图片描述

四、BeanPostProcessor接口

BeanPostProcessor又叫Bean的后置处理器,是Spring框架中IOC容器提供的一个扩展接口,在Bean初始化的前后进行一些处理工作。

BeanPostProcessor的源码如下:

public interface BeanPostProcessor {/*** Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}* or a custom init-method). The bean will already be populated with property values.* The returned bean instance may be a wrapper around the original.* <p>The default implementation returns the given {@code bean} as-is.* @param bean the new bean instance* @param beanName the name of the bean* @return the bean instance to use, either the original or a wrapped one;* if {@code null}, no subsequent BeanPostProcessors will be invoked* @throws org.springframework.beans.BeansException in case of errors* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet*/@Nullable//bean初始化方法调用前被调用default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}/*** Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}* or a custom init-method). The bean will already be populated with property values.* The returned bean instance may be a wrapper around the original.* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean* instance and the objects created by the FactoryBean (as of Spring 2.0). The* post-processor can decide whether to apply to either the FactoryBean or created* objects or both through corresponding {@code bean instanceof FactoryBean} checks.* <p>This callback will also be invoked after a short-circuiting triggered by a* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,* in contrast to all other BeanPostProcessor callbacks.* <p>The default implementation returns the given {@code bean} as-is.* @param bean the new bean instance* @param beanName the name of the bean* @return the bean instance to use, either the original or a wrapped one;* if {@code null}, no subsequent BeanPostProcessors will be invoked* @throws org.springframework.beans.BeansException in case of errors* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet* @see org.springframework.beans.factory.FactoryBean*/@Nullable//bean初始化方法调用后被调用default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}

代码如下:

/*** @Version: 1.0.0* @Author: Dragon_王* @ClassName: MyBeanPostProcess* @Description: TODO描述* @Date: 2024/1/21 23:40*/
@Component
public class MyBeanPostProcess implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);return bean;}
}
============================
@Configuration
@ComponentScan(("com.dragon.restart1"))
public class MyConfig {@Beanpublic BeanTest1 beanTest1(){return new BeanTest1();}@Beanpublic BeanTest2 beanTest2(){return new BeanTest2();}
}

运行结果如下:

BeanTest1被创建
postProcessBeforeInitialization...beanTest1=>com.dragon.restart1.BeanTest1@111d5c97
BeanTest1初始化
postProcessAfterInitialization...beanTest1=>com.dragon.restart1.BeanTest1@111d5c97
BeanTest2被创建
postProcessBeforeInitialization...beanTest2=>com.dragon.restart1.BeanTest2@29c17c3d
BeanTest2被初始化
postProcessAfterInitialization...beanTest2=>com.dragon.restart1.BeanTest2@29c17c3d
IoC容器创建完成
BeanTest2被销毁
BeanTest1销毁

通过上述运行结果可以发现使用BeanPostProcessor的运行顺序为
IOC容器实例化Bean---->调用BeanPostProcessor的postProcessBeforeInitialization方法---->调用bean实例的初始化方法---->调用BeanPostProcessor的postProcessAfterInitialization方法。


总结

以上就是Bean生命周期自定义初始化和销毁的讲解。

相关文章:

SpringBoot:Bean生命周期自定义初始化和销毁

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java项目分享》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、Bean注解指…...

Git--基本操作介绍(2)

Git 常用的是以下 6 个命令&#xff1a;git clone、git push、git add 、git commit、git checkout、git pull. 说明&#xff1a; workspace&#xff1a;工作区staging area&#xff1a;暂存区/缓存区local repository&#xff1a;版本库或本地仓库remote repository&#xf…...

第08章_面向对象编程(高级)(static,单例设计模式,理解mian方法,代码块,final,抽象类与抽象方法,接口,内部类,枚举类,注解,包装类)

文章目录 第08章_面向对象编程(高级)本章专题与脉络1. 关键字&#xff1a;static1.1 类属性、类方法的设计思想1.2 static关键字1.3 静态变量1.3.1 语法格式1.3.2 静态变量的特点1.3.3 举例1.3.4 内存解析 1.4 静态方法1.4.1 语法格式1.4.2 静态方法的特点1.4.3 举例 1.5 练习 …...

Java中Map接口常用的方法

java.util.Map接口中常用的方法&#xff1a; 1.Map和Collection没有继承关系 2.Map集合以key和value的方式存储数据&#xff1a;键值对 key和value都是引用数据类型 key和value都是存储对象的内存地址 key起到主导的地位&#xff0c;value是key的一个附属品 3.Map接口中常用的方…...

Linux软件包管理器yum

文章目录 前言概述Linux下载软件的三种方式源代码安装rpm安装yum安装 关于yum的相关操作查看软件包软件安装卸载软件 yum源问题 前言 在Windows系统中&#xff0c;如果我们要去下载软件&#xff0c;我们可以在该软件的官网中进行下载&#xff0c;或者在微软的额软件商店进行下…...

Linux中NFS服务器的搭建和安装

1.介绍&#xff1a; 网络文件系统即将本地系统放在网络上某一个位置的系统&#xff0c;基于UDP/IP使用nfs能够在不同计算机之间通过网络进行文件共享&#xff0c;能使使用者访问网络上其他计算机中的文件就像在访问自己的计算机一样&#xff0c;也就是说放在一个开发板上&#…...

c递归算法模型

使用递归算法模型可以较为自然地解决许多问题&#xff0c;尤其是对于那些数据结构层次比较清晰的问题&#xff0c;递归算法模型往往能够提供一种简单清晰的解法。 递归算法模型的核心思想是将一个大问题通过递归的方式拆分为若干个较小的问题&#xff0c;并不断递归下去直到问…...

力扣740. 删除并获得点数

动态规划 思路&#xff1a; 选择元素 x&#xff0c;获得其点数&#xff0c;删除 x 1 和 x - 1&#xff0c;则其他的 x 的点数也会被获得&#xff1b;可以将数组转换成一个有序 map&#xff0c;key 为 x&#xff0c; value 为对应所有 x 的和&#xff1b;则问题转换成了不能同…...

spring和springboot的区别

在当今的软件开发领域&#xff0c;Spring和Spring Boot无疑是Java开发者最常用的框架之一。尽管它们都源于Spring项目&#xff0c;但它们在设计和使用上有很大的不同。本文将深入探讨Spring和Spring Boot之间的主要区别&#xff0c;以及为什么有时候选择其中一个而不是另一个是…...

imgaug库图像增强指南(35):【iaa.Fog】——轻松创建自然雾气场景

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…...

网络安全--防御保护02

第二天重要的一个点是区域这个概念 防火墙的主要职责在于控制和防护---安全策略---防火墙可以根据安全策略来抓取流量之后做出对应的动作 防火墙的分类&#xff1a; 单一主机防火墙&#xff1a;专门有设备作为防火墙 路由集成&#xff1a;核心设备&#xff0c;可流量转发 分…...

UE5 C++学习笔记 常用宏的再次理解

1.随意创建一个类&#xff0c;他都有UCLASS()。GENERATED_BODY()这样的默认的宏。 UCLASS() 告知虚幻引擎生成类的反射数据。类必须派生自UObject. &#xff08;告诉引擎我是从远古大帝UObject中&#xff0c;继承而来&#xff0c;我们是一家人&#xff0c;只是我进化了其他功能…...

SpringBoot整合SSE

目录 1.SseController2. SseServiceSseServiceSseServiceImpl 3.SendMessageTask4.将定时任务加入启动类5.参考资料 1.SseController Slf4j RestController RequestMapping("sse") public class SseController {Autowiredprivate SseService sseService;RequestMappi…...

mysql-进阶篇

文章目录 存储引擎MySQL体系结构相关操作 存储引擎特点InnoDBInnoDB 逻辑存储结构 MyISAMMemory三个存储引擎之间的区别存储引擎的选择 索引1. 索引结构B-TreeB-Tree (多路平衡查找树)B-Tree演变过程 BTree与 B-Tree 的区别BTree演变过程 Hash 2.索引分类3.索引语法演示 4.SQL性…...

Js中的构造函数

在JavaScript中&#xff0c;构造函数是一种特殊类型的方法&#xff0c;用于创建并初始化一个新的对象。它通常使用 new 关键字来调用&#xff0c;并且通常以大写字母开头&#xff0c;以与其他非构造函数区分开来。 一个简单的构造函数示例&#xff1a; function Person(name,…...

[小程序]页面事件

一、下拉刷新 1.开启和配置 小程序中开启下拉刷新的方式有两种&#xff1a; ①全局开启下来刷新 在app.json的window节点中&#xff0c;设置enablePullDownRefresh设为ture。 ②局部开启下来刷新 在页面对应的json文件的的window节点中&#xff0c;设置enablePullDownRefresh设…...

vue echarts地图

下载地图文件&#xff1a; DataV.GeoAtlas地理小工具系列 范围选择器右侧行政区划范围中输入需要选择的省份或地市&#xff0c;选择自己想要的数据格式&#xff0c;这里选择了geojson格式&#xff0c;点右侧的蓝色按钮复制到浏览器地址栏中&#xff0c;打开的geojson文件内容…...

v38.Switch语句

1.Switch语句可以替代if-else语句 2.具体使用 Switch&#xff08;expression&#xff09; &#xff5b; case label&#xff1a;...... &#xff5d; ①将x与case后的label 进行比较&#xff1b; ②注意后面有冒号&#xff1b; ③从上往下开始检查case&#xff1b; ④如果…...

如何进行产品的人机交互设计?

产品的人机交互设计是指通过用户界面和用户体验设计来优化产品与用户之间的交互过程&#xff0c;从而提高产品的易用性、可用性和用户满意度。人机交互设计需要考虑用户的需求、行为模式、心理感受以及技术实现&#xff0c;下面我将介绍如何进行产品的人机交互设计。 首先&…...

【ARMv8M Cortex-M33 系列 7.3 -- EXC_RETURN 与 LR 及 PC 的关系详细介绍】

请阅读【嵌入式开发学习必备专栏 之 ARM Cortex-Mx专栏】 文章目录 背景EXC_RETURN 与 LR 及 PCcortex-m33 从异常返回后 各个寄存器出战顺序ARM 栈增长方式 背景 接着上篇文章&#xff1a;【ARMv8M Cortex-M33 系列 7.2 – HardFault 问题定位 1】&#xff0c;后面定位到是在…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

使用python进行图像处理—图像滤波(5)

图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值&#xff0c;以达到平滑&#xff08;去噪&#xff09;、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算&#xff0c;…...

MCP和Function Calling

MCP MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09; &#xff0c;2024年11月底&#xff0c;由 Anthropic 推出的一种开放标准&#xff0c;旨在统一大模型与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而…...

解密鸿蒙系统的隐私护城河:从权限动态管控到生物数据加密的全链路防护

摘要 本文以健康管理应用为例&#xff0c;展示鸿蒙系统如何通过细粒度权限控制、动态权限授予、数据隔离和加密存储四大核心机制&#xff0c;实现复杂场景下的用户隐私保护。我们将通过完整的权限请求流程和敏感数据处理代码&#xff0c;演示鸿蒙系统如何平衡功能需求与隐私安…...