Springboot - 5.Bean的生命周期
✍1. Bean的生命周期:
当然,我会详细描述每一步的作用。
🎷1. 实例化Bean:
- 这是Bean生命周期的第一步。Spring容器通过反射机制创建Bean的实例。
public class ExampleBean {// ... }
🎷2. 设置Bean的属性:
- Spring容器将根据配置文件设置Bean的属性。这是通过调用Bean的setter方法完成的。
public class ExampleBean {private String name;public void setName(String name) {this.name = name;}// ... }
🎷3. 调用BeanNameAware的setBeanName方法:
- 如果Bean实现了
BeanNameAware接口,Spring容器将调用setBeanName方法,传递Bean的ID。这允许Bean知道它在Spring容器中的ID。public class ExampleBean implements BeanNameAware {private String beanName;@Overridepublic void setBeanName(String name) {this.beanName = name;}// ... }
🎷4. 调用BeanFactoryAware的setBeanFactory方法:
- 如果Bean实现了
BeanFactoryAware接口,Spring容器将调用setBeanFactory方法,传递自身。这允许Bean知道它所属的容器。public class ExampleBean implements BeanFactoryAware {private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) {this.beanFactory = beanFactory;}// ... }
🎷5. 调用ApplicationContextAware的setApplicationContext方法:
- 如果Bean实现了
ApplicationContextAware接口,Spring容器将调用setApplicationContext方法,传递自身。这允许Bean知道它所属的应用上下文。public class ExampleBean implements ApplicationContextAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) {this.applicationContext = applicationContext;}// ... }
🎷6. 调用BeanPostProcessor的postProcessBeforeInitialization方法:
- 如果Bean实现了
BeanPostProcessor接口,Spring容器将在初始化方法之前调用postProcessBeforeInitialization方法。这允许对Bean的属性进行更改。public class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// ...return bean;}// ... }
🎷7. 调用InitializingBean的afterPropertiesSet方法:
- 如果Bean实现了
InitializingBean接口,Spring容器将在所有属性设置完成后调用afterPropertiesSet方法。public class ExampleBean implements InitializingBean {@Overridepublic void afterPropertiesSet() throws Exception {// ...}// ... }
🎷8. 调用自定义的初始化方法:
- 如果在Bean的定义中指定了自定义的初始化方法,Spring容器将调用它。
public class ExampleBean {public void init() {// ...}// ... }
🎷9. 调用BeanPostProcessor的postProcessAfterInitialization方法:
- 如果Bean实plement了
BeanPostProcessor接口,Spring容器将在初始化方法之后调用postProcessAfterInitialization方法。public class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// ...return bean;}// ... }
🎷10. Bean的使用:
- 现在,Bean已经准备好了,可以被应用程序使用。
🎷11. 调用DisposableBean的destroy方法:
- 如果Bean实现了
DisposableBean接口,Spring容器将在容器关闭时调用destroy方法。public class ExampleBean implements DisposableBean {@Overridepublic void destroy() throws Exception {// ...}// ... }
🎷12. 调用自定义的销毁方法:
- 如果在Bean的定义中指定了自定义的销毁方法,Spring容器将在容器关闭时调用它。
public class ExampleBean {public void destroy() {// ...}// ... }
🎷13. 下面是一个简单的Java配置示例:
@Configuration
public class AppConfig {@Bean(initMethod = "init", destroyMethod = "destroy")public ExampleBean exampleBean() {return new ExampleBean();}}
- 在这个示例中,
ExampleBean是一个简单的Java类,它有init和destroy方法,分别作为初始化和销毁方法。
🎷14. 流程图如下:
+-------------------+
| 实例化Bean |
+-------------------+|v
+-------------------+
| 设置Bean的属性 |
+-------------------+|v
+-------------------+
| 调用BeanNameAware |
| 的setBeanName方法 |
+-------------------+|v
+-------------------+
| 调用BeanFactoryAware|
| 的setBeanFactory方法 |
+-------------------+|v
+-------------------+
| 调用ApplicationContextAware|
| 的setApplicationContext方法 |
+-------------------+|v
+-------------------+
| 调用BeanPostProcessor |
| 的postProcessBeforeInitialization方法 |
+-------------------+|v
+-------------------+
| 调用InitializingBean|
| 的afterPropertiesSet方法 |
+-------------------+|v
+-------------------+
| 调用自定义的初始化方法 |
+-------------------+|v
+-------------------+
| 调用BeanPostProcessor |
| 的postProcessAfterInitialization方法 |
+-------------------+|v
+-------------------+
| Bean的使用 |
+-------------------+|v
+-------------------+
| 调用DisposableBean |
| 的destroy方法 |
+-------------------+|v
+-------------------+
| 调用自定义的销毁方法 |
+-------------------+
✍2. 如何使用Bean的生命周期:
在Spring Boot中,我们可以使用Java配置、注解和自定义的BeanPostProcessor来使用Bean的生命周期。
🎷1. 使用Java配置:
-
我们可以使用
@Bean注解的initMethod和destroyMethod属性来指定Bean的初始化和销毁方法。@Configuration public class AppConfig {@Bean(initMethod = "init", destroyMethod = "destroy")public ExampleBean exampleBean() {return new ExampleBean();}}public class ExampleBean {public void init() {System.out.println("ExampleBean 初始化");}public void destroy() {System.out.println("ExampleBean 销毁");}}在这个示例中,
ExampleBean是一个简单的Java类,它有init和destroy方法,分别作为初始化和销毁方法。
🎷2. 使用@PostConstruct和@PreDestroy注解:
-
我们可以使用
@PostConstruct注解来标记Bean的初始化方法,使用@PreDestroy注解来标记Bean的销毁方法。@Component public class ExampleBean {@PostConstructpublic void init() {System.out.println("ExampleBean 初始化");}@PreDestroypublic void destroy() {System.out.println("ExampleBean 销毁");}}在这个示例中,
ExampleBean是一个简单的Java类,它有init和destroy方法,分别作为初始化和销毁方法。
🎷3. 使用InitializingBean和DisposableBean接口:
-
我们可以让Bean实现
InitializingBean接口和DisposableBean接口。@Component public class ExampleBean implements InitializingBean, DisposableBean {@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("ExampleBean 初始化");}@Overridepublic void destroy() throws Exception {System.out.println("ExampleBean 销毁");}}在这个示例中,
ExampleBean是一个简单的Java类,它实现了InitializingBean接口和DisposableBean接口。
🎷4. 使用自定义的BeanPostProcessor:
-
我们可以创建一个自定义的
BeanPostProcessor,并在postProcessBeforeInitialization方法和postProcessAfterInitialization方法中添加自定义的逻辑。@Component public class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof ExampleBean) {System.out.println("ExampleBean 初始化之前");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof ExampleBean) {System.out.println("ExampleBean 初始化之后");}return bean;}}@Component public class ExampleBean {// ...}在这个示例中,
CustomBeanPostProcessor是一个自定义的BeanPostProcessor,它在ExampleBean的初始化之前和之后添加了自定义的逻辑。
✍3. 优缺点和使用场景
当描述每个Bean的生命周期阶段时,我已经包括了各个阶段的作用、使用场景以及优缺点。每个阶段都对应着特定的操作和目的,以下是对每个阶段的描述和附加信息:
🎷 1. 实例化Bean:
- 作用:创建Bean的实例,使用反射机制根据配置信息生成一个新的对象。
- 使用场景:在这个阶段,主要是实例化对象,通常不涉及太多业务逻辑。
- 优缺点:这个阶段没有特定的优缺点,它是整个生命周期的起点,为后续的操作提供了基础。
🎷 2. 设置Bean的属性:
- 作用:根据配置文件设置Bean的属性,通过调用setter方法完成。
- 使用场景:在这个阶段,属性被设置为配置文件中指定的值,准备好被后续的初始化方法使用。
- 优缺点:这个阶段是为了确保Bean的属性已正确设置,没有明显的优缺点。
🎷 3. 调用BeanNameAware的setBeanName方法:
- 作用:如果Bean实现了
BeanNameAware接口,容器将传递Bean的ID,让Bean知道自己在容器中的名称。 - 使用场景:当Bean需要知道自己在容器中的名称时,可以实现此接口。
- 优缺点:这个阶段可以让Bean获取自己的ID,有助于Bean在后续的操作中使用这个信息。
🎷 4. 调用BeanFactoryAware的setBeanFactory方法:
- 作用:如果Bean实现了
BeanFactoryAware接口,容器将传递自身,让Bean知道所属的容器。 - 使用场景:当Bean需要与容器进行交互,例如获取其他Bean,可以实现此接口。
- 优缺点:这个阶段允许Bean与容器进行交互,获取其他Bean的引用,但在较新的Spring版本中,通常使用更现代的依赖注入方式。
🎷 5. 调用ApplicationContextAware的setApplicationContext方法:
- 作用:如果Bean实现了
ApplicationContextAware接口,容器将传递应用上下文,让Bean知道所属的应用上下文。 - 使用场景:当Bean需要与应用上下文进行交互,例如获取消息资源、执行AOP等,可以实现此接口。
- 优缺点:这个阶段允许Bean与应用上下文进行交互,获取应用上下文中的各种资源和服务。
🎷 6. 调用BeanPostProcessor的postProcessBeforeInitialization方法:
- 作用:如果Bean实现了
BeanPostProcessor接口,容器将在初始化方法之前调用此方法,允许对Bean的属性进行更改。 - 使用场景:当需要在Bean初始化之前对属性进行修改或处理时,可以实现此接口。
- 优缺点:这个阶段允许对Bean进行额外的定制和处理,但需要小心不要影响初始化流程。
🎷 7. 调用InitializingBean的afterPropertiesSet方法:
- 作用:如果Bean实现了
InitializingBean接口,容器将在所有属性设置完成后调用此方法,用于执行额外的初始化逻辑。 - 使用场景:当需要在属性设置完成后执行初始化逻辑时,可以实现此接口。
- 优缺点:这个阶段允许在属性设置完成后执行自定义的初始化操作,但是与Spring API的耦合度较高。
🎷 8. 调用自定义的初始化方法:
- 作用:调用Bean定义中指定的自定义初始化方法,执行特定的初始化逻辑。
- 使用场景:当需要在Bean初始化阶段执行特定的业务逻辑时,可以通过配置自定义的初始化方法。
- 优缺点:这个阶段允许在初始化过程中执行业务逻辑,但需要谨慎处理与初始化过程的关系。
🎷 9. 调用BeanPostProcessor的postProcessAfterInitialization方法:
- 作用:如果Bean实现了
BeanPostProcessor接口,容器将在初始化方法之后调用此方法,允许对Bean进行后处理。 - 使用场景:当需要在Bean初始化后对Bean进行额外的处理,例如AOP代理、属性设置等,可以实现此接口。
- 优缺点:这个阶段允许在Bean初始化后进行额外的处理,但需要注意不要破坏Bean的状态。
🎷 10. Bean的使用:
- 作用:Bean已经准备好可以被应用程序使用。
- 使用场景:在这个阶段,应用程序可以开始使用Bean的功能,进行业务逻辑操作。
🎷 11. 调用DisposableBean的destroy方法:
- 作用:如果Bean实现了
DisposableBean接口,容器将在容器关闭时调用此方法,执行销毁操作。 - 使用场景:当需要在Bean被销毁前执行清理操作,例如释放资源、关闭连接等,可以实现此接口。
- 优缺点:这个阶段允许在容器关闭前执行清理操作,但与Spring API的耦合度较高。
🎷 12. 调用自定义的销毁方法:
- 作用:调用Bean定义中指定的自定义销毁方法,执行特定的销毁逻辑。
- 使用场景:当需要在Bean销毁阶段执行特定的业务逻
辑时,可以通过配置自定义的销毁方法。
- 优缺点:这个阶段允许在销毁过程中执行业务逻辑,但需要注意不要破坏销毁过程的完整性。
相关文章:
Springboot - 5.Bean的生命周期
✍1. Bean的生命周期: 当然,我会详细描述每一步的作用。 🎷1. 实例化Bean: 这是Bean生命周期的第一步。Spring容器通过反射机制创建Bean的实例。public class ExampleBean {// ... }🎷2. 设置Bean的属性: Spring容器将根据配置…...
华为云 sfs 服务浅谈
以root用户登录弹性云服务器。 以root用户登录弹性云服务器。 安装NFS客户端。 查看系统是否安装NFS软件包。 CentOS、Red Hat、Oracle Enterprise Linux、SUSE、Euler OS、Fedora或OpenSUSE系统下,执行如下命令: rpm -qa|grep nfs Debian或Ubuntu系统下…...
CSS中如何实现元素的渐变背景(Gradient Background)效果?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS 渐变背景效果⭐ 线性渐变背景⭐ 径向渐变背景⭐ 添加到元素的样式⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&…...
buildroot修改内核防止清理重新加载办法
当你使用 Buildroot 构建 Linux 内核时,如果对内核文件进行了手动修改,重新执行 Buildroot 的构建过程将会覆盖你所做的修改。这是因为 Buildroot会根据配置重新下载、提取和编译内核。 为了避免在重新构建时覆盖你的修改,可以采取以下两种方…...
Vue框架--Vue中的事件
1.事件处理 事件的基本使用: (1).使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名; (2).事件的回调需要配置在methods对象中,最终会在vm上; (3).methods中配置的函数,不要用箭头函数!否则this就不是vm了; (4).methods中配置的函数,都是被Vue所管理的函数,this的…...
1921. 消灭怪物的最大数量
原题地址 解法一 排序贪心即可。思想为先计算出每一个怪兽到达城市的时间,然后排序,有小到大进行消灭,此时的下标可视作时间。当怪兽到达城市的时间超过或等于当前时间时,即已经到达了城市,游戏失败,下标…...
创建一个空的vue项目,配置及步骤
查看需要的环境及插件版本 创建vue命令 默认配置 手动配置 其他 hash和history的区别: hash 模式,url后,会带着#,改变hash,页面不会刷新,不会更改整个页面,只会更改#后面路由配置的内容&#x…...
一篇文章教会你如何编写一个简单的Shell脚本
文章目录 简单Shell脚本编写1. 简单脚本编写2. Shell脚本参数2.1 Shell脚本参数判断2.1.1 文件测试语句2.1.2 逻辑测试语句2.1.3 整数值测试语句2.1.4 字符串比较语句 3. Shell流程控制语句3.1 if 条件测试语句3.1.1 if...3.1.2 if...else...3.1.3 if...elif...else 4. Shell脚…...
SSM框架-spring
SSM框架参考 spring...
聊一下C#中的lock
在C#中,lock 是用于实现多线程同步的关键字。它用于创建一个互斥锁(Mutex),以确保在同一时间只有一个线程可以访问被锁定的代码块。这在多线程环境中是很重要的,因为如果多个线程同时访问共享资源,可能会导…...
学会Mybatis框架:让你的开发事半功倍【五.Mybatis关系映射】
目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 导语 一、一对一的关系映射 1.表结构 2.resultMap配置 3.测试关系映射 二、一对多的关系映射 1.表结构 2.resultMap配置 3.测试关系映射 三、多对多的关系映射 1.表结构…...
《TCP/IP网络编程》阅读笔记--基于Windows实现Hello Word服务器端和客户端
目录 1--Hello Word服务器端 2--客户端 3--编译运行 3-1--编译服务器端 3-2--编译客户端 3-3--运行 1--Hello Word服务器端 // gcc hello_server_win.c -o hello_server_win -lwsock32 // hello_server_win 9190 #include <stdio.h> #include <stdlib.h> #i…...
Java-Optional类
概述 Optional是JAVA 8引入的一个类,用于处理可能为null的值。 利用Optional可以减少代码中if-else的判断逻辑,增加代码的可读性。且可以减少空指针异常的发生,增加代码的安全性。 常用的方法 示例 代码 public class OptionalTest {pub…...
AJAX学习笔记1发送Get请求
传统请求有哪些方式,及缺点 传统请求有哪些? 1.直接在浏览器地址栏上输入URL. 2.点击超连接. <a href"/上下文/请求地址">超链接请求</a> ---->相对路径 <a href"http://www.baidu.com">超链接请求</a> ---->绝对路…...
Elasticsearch 高级搜索技巧和最佳实践
Elasticsearch 高级搜索技巧和最佳实践 Elasticsearch 是一个开源的分布式搜索和分析引擎,它支持实时地存储、搜索和分析大规模数据。它被广泛应用于各行各业,用于构建高性能的搜索引擎、日志分析系统、电子商务推荐系统等。 本文将介…...
解决 .csv 文件上传到 pgsql 的字符报错问题
目录 背景问题解决办法 背景 上传 .csv 文件进行数据导入到 pg 时,报错显示如下: ods.tbl_inp_fee_detail.csv数据上传失败 报错信息:org.postgresql.util.PSQLException: ERROR: invalid byte sequence for encoding "UTF8": 0x00 Where: C…...
linux自动挂载并添加用户权限
目录 写在前面自动挂载完 写在前面 1、本文内容 linux挂载文件后,没有文件权限,使用uid和gid指定所需的所有者和所属组 2、平台/环境 linux 3、转载请注明出处: https://blog.csdn.net/qq_41102371/article/details/132539384 自动挂载 开…...
【C++】学习STL中的stack和queue
❤️前言 今天这篇博客的内容主要关于STL中的stack、queue和priority_queue三种容器。 正文 stack和queue的使用方式非常简单,我们只要根据之前学习数据结构的经验和文档介绍就可以轻松上手。于是我们直接开始对它们的模拟实现。 stack和queue的模拟实现 stack和q…...
Java捕获异常
在Java中,凡是可能抛出异常的语句,都可以用try ... catch捕获。把可能发生异常的语句放在try { ... }中,然后使用catch捕获对应的Exception及其子类。 使用try ... catch ... finally时: 多个catch语句的匹配顺序非常重要…...
【LLM】快速开始 LangChain
theme: orange LangChain是一个软件开发工具包,它通过将组件链接在一起并公开简单统一的API,简化了大型语言模型和应用程序的集成。本篇文章将会简要介绍,让各位开发者对其有一个整体的认识。 前言 如果你是一名软件开发人员,努力…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
