全注解下的SpringIoc 续2-bean的生命周期
spring中bean的生命周期
上一个小节梳理了一下Spring Boot的依赖注入的基本知识,今天来梳理一下spring中bean的生命周期。
下面,让我们一起看看bean在IOC容器中是怎么被创建和销毁的。
bean的生命周期大致分为四个部分:
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.第六阶段 三、总结 前言 在上一章中我们聊到了事务有四大特性:原子性、一致性、隔离性、持久性。本篇文章就持久性重点聊一下,…...

智加科技+舍弗勒,首发量产正向开发的智能重卡冗余转向
对于自动驾驶赛道来说,感知、规划和控制,除了计算平台、算法等核心上层软硬件支持,底盘控制系统同样是关键一环。事实上,从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模式 ? “反应”器名字中”反应“的由来: “反应”即“倒置”,“控制逆转”,具体事件处理程序不调用反应器,而向反应器注册一个事件处理器,表示自己对某些事件感兴趣࿰…...
MySQL统计函数count详解
count()概述 count() 是一个聚合函数,返回指定匹配条件的行数。开发中常用来统计表中数据,全部数据,不为null数据,或者去重数据 count(1)和count()和count(列名)的区别 1.函数说明 count(1):统计所有的记录࿰…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...