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

全注解下的SpringIoc 续2-bean的生命周期

spring中bean的生命周期

上一个小节梳理了一下Spring Boot的依赖注入的基本知识,今天来梳理一下spring中bean的生命周期。
下面,让我们一起看看bean在IOC容器中是怎么被创建和销毁的。
bean的生命周期大致分为四个部分:

定义
初始化
生存期
销毁

bean的定义和初始化

大致流程如下:

Created with Raphaël 2.3.0 开始 资源定位(通过@ComponentScan注解定义的扫描规则去寻找被@Component、@Controller、@Service......等注解标记的类) 资源解析、并且将定义的信息保存起来 定义发布:将bean的定义信息发布到ioc容器中 bean的初始化 结束

默认情况下,spring会在启动时完成对bean的定义、发布以及初始化,但是,有时候我们并不想让spring在启动时就完成bean的初始化,更想的是在我们用到它时,才去完成初始化的动作,最常见的就是循环依赖的场景了。
而解决这个问题就需要用到spring的延迟初始化的机制了。

spring的延迟初始化bean机制

可以使用2中方法使bean进行延迟初始化:

@ComponentScan注解的lazyInit属性

@ComponentScan(basePackages = {"com.zzm.iocbeanlifeperiod"},lazyInit = true)

设置该属性为true后,对应的扫描规则下的bean都会进行延迟初始化

@Lazy注解

该注解用于指定某一个依赖的bean进行延迟初始化,用法如下:

	@Autowired@Lazyprivate Animal cat;

bean的初始化生命周期的各个阶段

好了,现在我们正式看看bean的生命周期的各个阶段,如下图所示:
在这里插入图片描述
这个流程介绍了bean从初始化到销毁的过程。
注意:流程中的setApplicationContext方法有些特殊,即使你定义了 ApplicationContextAware 接口,但是有时候并不会调用,这要根据你的 IoC器来决定。 我们知道, Spring IoC 容器最低的要求是实 BeanFactory 接口,而不是ApplicationContext 接口, 对于那些没有实现 Application Cont xt 接口的容器 ,在生命周期对应的 ApplicationContextAware 定义的方法也是不会被调用的,只有实现了 Applic ationContext 接口的容器,才会在生命周期调用 ApplicationContextAware 定义的 setApplicationContext
方法。

接下来,让我们一起测试一下bean的生命周期。
首先创建一个类,同时让它实现流程中的这些接口,代码如下:

@Component
@Slf4j
public class BeanLifePeriod implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {log.warn("【{}】调用了BeanFactoryAware的setBeanFactory",this.getClass().getSimpleName());}@Overridepublic void setBeanName(String name) {log.warn("【{}】调用了BeanNameAware的setBeanName",this.getClass().getSimpleName());}@Overridepublic void destroy() throws Exception {log.warn("【{}】调用了DisposableBean的destroy",this.getClass().getSimpleName());}@PreDestroypublic void destroyMyself() {log.warn("【{}】调用了注解@PreDestroy定义的自定义销毁方法",this.getClass().getSimpleName());}@Overridepublic void afterPropertiesSet() throws Exception {log.warn("【{}】调用了InitializingBean的afterPropertiesSet",this.getClass().getSimpleName());}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {log.warn("【{}】调用了ApplicationContextAware的setApplicationContext",this.getClass().getSimpleName());}@PostConstructpublic void init(){log.warn("【{}】调用了注解@PostConstruct定义的自定义初始化方法",this.getClass().getSimpleName());}
}

因为BeanPostProcessor接口的方法是针对于所有的bean的,所以我们这里单独创建一个类来实现它:

@Component
@Slf4j
public class BeanPostProcessorExample implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {log.warn("BeanPostProcessor调用postProcessBeforeInitialization方法,参数【{},{}】", bean.getClass().getSimpleName(), bean);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {log.warn("BeanPostProcessor调用postProcessAfterInitialization方法,参数【{},{}】", bean.getClass().getSimpleName(), bean);return bean;}
}

接下来,创建ioc配置类和测试类

@ComponentScan(basePackages = {"com.zzm.iocbeanlifeperiod"})
@Configuration
@Slf4j
public class LifePeriodAppConfig {}public class IocBeanLifePeriod {public static void main(String[] args) throws InterruptedException {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(LifePeriodAppConfig.class);context.close();}
}

运行main方法,可以看到如下日志:
在这里插入图片描述
上面的流程可用于自定义的bean,但是有时候bean不是我们自己定义的,而是第三方的bean,那怎么办呢?
在小节全注解下的IOC中我们介绍了@Bean注解,它可以用来向容器发布第三方的bean,所以通过它,我们也可以自定义初始化和销毁的方法,用法如下:

@ComponentScan(basePackages = {"com.zzm.iocbeanlifeperiod"})
@Configuration
@Slf4j
public class LifePeriodAppConfig {@Bean(value = "lifePeriodUser",initMethod = "init",destroyMethod = "destroy")public LifePeriodUser getUser(){return new LifePeriodUser().setId(3L).setUserName("Bean手动注入").setNote("Bean手动注入");}
}@Data
@Accessors(chain = true)
@Slf4j
public class LifePeriodUser {private Long id;private String userName;private String note;public void init(){log.warn("【{}】调用了自定义用户初始化方法",this.getClass().getSimpleName());}public void destroy(){log.warn("【{}】调用了自定义用户销毁方法",this.getClass().getSimpleName());}
}

感兴趣的小伙伴可以自己尝试下,今天就到这里了。。。。。

相关文章:

全注解下的SpringIoc 续2-bean的生命周期

spring中bean的生命周期 上一个小节梳理了一下Spring Boot的依赖注入的基本知识,今天来梳理一下spring中bean的生命周期。 下面,让我们一起看看bean在IOC容器中是怎么被创建和销毁的。 bean的生命周期大致分为四个部分: #mermaid-svg-GFXNEU…...

【VQ-VAE代码实战】Neural Discrete Representation Learning

【VQ-VAE代码实战】Neural Discrete Representation Learning 0、前言1、简介2、Basic IdeaLoss3、代码Load DataVector Quantizer LayerEncoder & Decoder ArchitectureTrainPlot LossView ReconstructionsView EmbeddingReference0、前言 论文地址:基于神经网络的,离散…...

gpt3.5和gpt4区别-gpt3.5和gpt4

gpt系列 GPT系列是OpenAI公司开发的一组基于人工智能深度学习技术的自然语言处理模型。GPT代表Generative Pre-trained Transformer,即预训练生成模型。目前,GPT模型已经推出了三代(GPT-1,GPT-2,GPT-3)&am…...

java获取当前系统时间

在Java中,可以使用以下几种方法获取当前系统时间: 方法1:使用java.util.Date类 java import java.util.Date; public class Main { public static void main(String[] args) { Date date new Date(); System.out.println("当前时间&…...

pbootcms自动配图出图插件

pbootcms文章无图自动出图配图插件的优点 1、提高文章的可读性和吸引力:插入图片可以丰富文章的内容和形式,增强读者的阅读体验和吸引力,提高文章的点击率和转化率。 2、节省时间和精力:手动添加图片需要花费大量时间和精力去寻找…...

手动测试台架搭建,让你的车载测试更轻松

目录:导读 引言 1、概述 2、主要内容 3、汽车测试台架分类 4、汽车测试台架分类 5、汽车测试台架分类台架测试输人台架硬件搭建CANoe台架搭建 6、台架测试输入? 7、需求规范是功能测试用例设计来源测试结果的判断﹔包括∶客户需求(功能规范)需求分…...

分组双轴图:揭示数据中的关联性和趋势变化

简介 分组双轴图是一种数据可视化图表,指有多个(≥2)Y轴的数据图表,多为分组柱状图折线图的结合,图表显示更为直观,可以很好地展示不同指标之间的关系,帮助用户更好地理解数据,做出…...

MATLAB函数封装1:生成QT可以调用的.dll动态链接库

在进行相关算法的开发和设计过程中,MATLAB具有特别的优势,尤其是对于矩阵运算的处理,具有很多现成的方法和函数可以进行调用,同时MATLAB支持把函数封装成不同的语言方便完成算法的集成。 这里记录利用MATLAB封装成C动态链接库&…...

【算法题】2400. 恰好移动 k 步到达某一位置的方法数目

题目: 给你两个 正 整数 startPos 和 endPos 。最初,你站在 无限 数轴上位置 startPos 处。在一步移动中,你可以向左或者向右移动一个位置。 给你一个正整数 k ,返回从 startPos 出发、恰好 移动 k 步并到达 endPos 的 不同 方法…...

探索【Stable-Diffusion WEBUI】的插件:骨骼姿态(OpenPose)

文章目录 (零)前言(一)骨骼姿态(OpenPose)系列插件(二)插件:PoseX(三)插件:Depth Lib(四)插件:3D …...

MySQL数据落盘原理(redo、undo、binlog、2PC、double write等。)

文章目录 前言一、架构图1、MySQL架构图2、InnoDB架构图 二、落盘分析1.第一阶段2.第二阶段3.第三阶段4.第四阶段5.第五阶段6.第六阶段 三、总结 前言 在上一章中我们聊到了事务有四大特性:原子性、一致性、隔离性、持久性。本篇文章就持久性重点聊一下&#xff0c…...

智加科技+舍弗勒,首发量产正向开发的智能重卡冗余转向

对于自动驾驶赛道来说,感知、规划和控制,除了计算平台、算法等核心上层软硬件支持,底盘控制系统同样是关键一环。事实上,从Demo到规模化量产,更好的车身控制能力以及冗余备份,也是自动驾驶公司迈入2.0阶段的…...

C++类的模拟实现

📟作者主页:慢热的陕西人 🌴专栏链接:C 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 本博客主要内容讲解了简单模拟实现string类 C类的模拟实现 文章目录 C类的…...

耐腐蚀高速电动针阀在半导体硅片清洗机化学药液流量控制中的应用

摘要:化学药液流量的精密控制是半导体湿法清洗工艺中的一项关键技术,流量控制要求所用调节针阀一是开度电动可调、二是具有不同的口径型号、三是高的响应速度,四是具有很好的耐腐蚀性,这些都是目前提升半导体清洗设备性能需要解决…...

助力工业物联网,工业大数据之ODS层及DWD层建表语法【七】

文章目录 ODS层及DWD层构建01:课程回顾02:课程目标03:数仓分层回顾04:Hive建表语法05:Avro建表语法 ODS层及DWD层构建 01:课程回顾 一站制造项目的数仓设计为几层以及每一层的功能是什么? ODS&…...

Windows环境下C++ 安装OpenSSL库 源码编译及使用(VS2019)

参考文章https://blog.csdn.net/xray2/article/details/120497146 之所以多次一举自己写多一篇文章,主要是因为原文内容还是不够详细。而且我安装的时候碰到额外的问题。 1.首先确认一下自己的代码是Win32的还是Win64的,我操作系统是64的,忘…...

TensorFlow高阶API和低阶API

TensorFlow提供了众多的API,简单地可以分类为高阶API和低阶API. API太多太乱也是TensorFlow被诟病的重点之一,可能因为Google的工程师太多了,社区太活跃了~当然后来Google也意识到这个问题,在TensorFlow 2.0中有了很大的改善。本文…...

强训之【参数解析和跳石板】

目录 1.参数解析1.1题目描述1.2思路1.3代码 2.跳石板2.1题目2.2思路2.3代码 3.选择题 1.参数解析 1.1题目描述 在命令行输入如下命令: xcopy /s c:\ d:\e, 各个参数如下: 参数1:命令字xcopy 参数2:字符串/s 参数…...

Redis队列Stream、Redis多线程详解(三)

Redis中的线程和IO模型 什么是Reactor模式 ? “反应”器名字中”反应“的由来: “反应”即“倒置”,“控制逆转”,具体事件处理程序不调用反应器,而向反应器注册一个事件处理器,表示自己对某些事件感兴趣&#xff0…...

MySQL统计函数count详解

count()概述 count() 是一个聚合函数,返回指定匹配条件的行数。开发中常用来统计表中数据,全部数据,不为null数据,或者去重数据 count(1)和count()和count(列名)的区别 1.函数说明 count(1):统计所有的记录&#xff0…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

测试markdown--肇兴

day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...

DeepSeek越强,Kimi越慌?

被DeepSeek吊打的Kimi,还有多少人在用? 去年,月之暗面创始人杨植麟别提有多风光了。90后清华学霸,国产大模型六小虎之一,手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水,单月光是投流就花费2个亿。 疯…...