【spring】Bean的生命周期回调函数和Bean的循环依赖

目录

1、Bean的生命周期

2、Bean的生命周期回调函数 

2.1、初始化的生命周期回调

2.2、销毁的生命周期回调

3、Bean的循环依赖

1、Bean的生命周期

        spring的bean的生命周期主要是创建bean的过程,一个bean的生命周期主要是4个步骤:实例化,属性注入,初始化,销毁

再详细一点可以拆分为:

(1)配置bean,通过@Component @Bean等方式都可以。

(2)加载Spring容器

(3)实例化,例如:(BeanService beanService = new BeanService())

(4)解析依赖注入(解析@Autowired @Value等自动注入注解)

(5)初始化(调用初始化回调方法,由程序员来配置)

(6)最终放入一个Map集合,Map<beanName, bean对象>

(7)spring容器.getBean("beanName")---->Map<beanName, bean对象>

(8)spring容器关闭 bean就会销毁(调用销毁回调方法,由程序员来配置)

2、Bean的生命周期回调函数 

2.1、初始化的生命周期回调

初始化(调用初始化回调方法,由程序员来配置),有三种方式来配置初始化回调方法

示例:

//自定义类LtService
public class LtService implements InitializingBean {// 基于接口实现初始化回调方法,重写了InitializingBean接口中的afterPropertiesSet()方法@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("接口:初始化");//接口实现初始化回调方法}// 基于注解实现初始化回调方法@PostConstructpublic void init() throws Exception {System.out.println("注解@PostConstruct:初始化");//注解@PostConstruct实现初始化回调方法}// 基于initMethod属性实现初始化回调方法public void init2() throws Exception {System.out.println("initMethod属性:初始化");//initMethod属性实现初始化回调方法}
}//测试类LifeCallbackTest
@SpringBootTest(classes = LifeCallbackTest.class)
public class LifeCallbackTest {//通过@Bean的方式把LtService配置成bean@Bean(initMethod = "init2")public LtService ltService(){return new LtService();}@Testpublic void test(@Autowired LtService ltService){System.out.println(ltService.getClass());}
}

从上面的结果可以看出他们的顺序是:先注解,再接口,最后initMethod属性

小补充:

2.2、销毁的生命周期回调

1.在springboot中当jvm进程结束后会自动调用容器.close0),自动销毁bean

2.在spring中,需要手动调用容器.close()来销毁bean

销毁(调用销毁回调方法,由程序员来配置),有三种方式来配置销毁回调方法

示例:

//自定义类LtService
//public class LtService implements InitializingBean , DisposableBean {
public class LtService implements DisposableBean {// 基于接口实现销毁回调方法,重写了DisposableBean接口中的destroy()方法@Overridepublic void destroy() throws Exception {System.out.println("接口:销毁");//接口实现销毁回调方法}// 基于注解实现销毁回调方法@PreDestroypublic void destroy2() throws Exception {System.out.println("注解@PreDestroy:销毁");//注解@PreDestroy实现销毁回调方法}// 基于destroyMethod属性实现销毁回调方法@PostConstructpublic void destroy3() throws Exception {System.out.println("destroyMethod属性:初始化");//destroyMethod属性实现销毁回调方法}
}//测试类
@SpringBootTest(classes = LifeCallbackTest.class)
public class LifeCallbackTest {//@Bean(initMethod = "init2", destroyMethod = "destroy3")@Bean(destroyMethod = "destroy3")public LtService ltService(){return new LtService();}@Testpublic void test(@Autowired LtService ltService){System.out.println(ltService.getClass());}
}

从上面的结果可以看出他们的顺序是:先注解,再接口,最后destroyMethod属性

3、Bean的循环依赖

        循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A。如下图:

        注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。

        Spring已经帮我们解决了循环依赖这个问题,这涉及到Spring底层源码的概念(Spring怎么解决的循环依赖)。但是,在SpringBoot中会报错,因为SpringBoot认为是一种不合理的设计

循环依赖在SpringBoot中会报错的解决方式:

1、在配置文件中放开循环依赖的限制

#放开循环依赖的限制
spring.main.allow-circular-references=true

2、代码设计层面:

a.把依赖的方法,直接写在本类中

b.添加一个中间类, 中间类去依赖A\B,然后让中间类去阻止他们的依赖方法

3、延迟注入

a.添加需要依赖的构造函数参数

b.添加@Lazy注解

@Lazy
public BeanA(BeanB beanb){this.beanb = beanb;
}@Lazy
public Bean(BeanA beana){this.beana = beana;
}

推荐: 

【Spring】IOC/DI中常用的注解@Lazy、@Scope与@Conditional-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/138277932?spm=1001.2014.3001.5501【Spring】IOC/DI中常用的注解@Order与@DependsOn-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/138167160?spm=1001.2014.3001.5501【Spring】依赖注入(DI)时常用的注解@Autowired和@Value_配置类 使用@autowired 类型注入-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_65277261/article/details/137784706?spm=1001.2014.3001.5501

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/7509.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频剪辑图文实例:一键操作,轻松实现视频批量片头片尾减时

视频剪辑是现代媒体制作中不可或缺的一环&#xff0c;而批量处理视频更是许多专业人士和爱好者的常见需求。在剪辑过程中&#xff0c;调整视频的片头片尾时长可以显著提升视频的质量和观感。本文将通过图文实例的方式&#xff0c;向您展示如何一键操作&#xff0c;轻松实现视频…

直播录屏怎么录?分享3种方法

随着网络直播的兴起&#xff0c;直播录屏已成为众多网友记录精彩瞬间、分享有趣内容的重要工具。直播录屏不仅能帮助我们回顾和保存直播中的精彩片段&#xff0c;还能为创作者提供更多的素材和灵感。 本文将为大家介绍3种直播录屏的方法&#xff0c;帮助大家能够更好地利用这一…

【IEEE独立出版|往届均已成功检索】ISPDS 2024诚邀投稿参会

第五届信息科学与并行、分布式处理国际学术会议&#xff08;ISPDS 2024&#xff09; 2024 5th International Conference on Information Science, Parallel and Distributed Systems 2024年5月31-6月2日 | 中国广州NEWS&#xff1a;会议已在格林威治大学官网上线会议已经上线到…

学术咸鱼入门指南(2)

巧用思维导图阅读文献 化整为零&#xff1a;读文献&#xff0c;从拆分文章的结构开始 大家在初步接触自己学科的论文时&#xff0c;要了解清楚基本的范式&#xff0c;日后读起来就比较顺了。 科研论文的第一部分&#xff0c;是文章的标题&#xff0c;摘要和关键词&#xff0…

【MySQL】连接查询(JOIN 关键字)—— 图文详解:内连接、外连接、左连接、左外连接、右连接、右外连接

文章目录 连接查询驱动表连接查询分类 内连接&#xff08;INNER JOIN&#xff09;内连接 —— 等值连接内连接 —— 自然连接&#xff08;NATURAL JOIN&#xff09;内连接 —— 交叉连接&#xff08;笛卡尔积&#xff09; 外连接&#xff08;OUTER JOIN&#xff09;外连接 ——…

nodejs里面的 http 模块介绍和使用

Node.js的HTTP模块是一个核心模块&#xff0c;它提供了很多功能来创建HTTP服务器和发送HTTP请求。 http.Server是一个基于事件的http服务器&#xff0c;内部是由c实现的&#xff0c;接口是由JavaScript封装。 http.request是一个http客户端工具。 用户向服务器发送数据。 创…

嵌入式RTOS面试题目

用过哪些嵌入式操作系统&#xff1f;使⽤RTOS和裸机代码开发有什么区别&#xff08;优缺点&#xff09;&#xff1f; 之前的⼀个项⽬是采⽤裸机代码开发的&#xff0c;写起来还⾏&#xff0c;通过状态机来管理业务逻辑和各种外设。 但是随着外设的增加&#xff0c;任务之间的…

CSDN我的创作纪念日128天||不忘初心|努力上进|勇往直前

机缘 Hello&#xff0c;大家好&#xff0c;我是景天&#xff0c;其实很早之前我就加入到了CSND的大军&#xff0c;但那是我还是个小白&#xff0c;经常回来CSND汲取养料&#xff0c;就这样慢慢的来提升自己&#xff0c;强大自己。经过多年的学习&#xff0c;积累与总结&#x…

Davinci工程开发方法论

基本概念 Flash Driver是下载到RAM里面的bin文件 Boot Manager是ROM上启动运行的第一个实例&#xff0c;可以是独立的bin文件&#xff0c;可以是集成在FBL里面。 Bootloader存储在ROM里面的bin文件 Demo Appl一个示例模板&#xff0c;用来跳转到Bootloader的&#xff0c;也是一…

本地的git仓库和远程仓库

文章目录 1. 远程创建仓库2. 关联远程和本地代码3. 推送本地分支到远程 1. 远程创建仓库 2. 关联远程和本地代码 上面创建完后会得到一个git仓库的链接&#xff0c;有SSH或者http的 http://gitlab.xxxxx.local:18080/xxxxx/dvr_avm.git ssh://gitgitlab.xxxxx.local:10022/xx…

220V转18V500mA非隔离恒压WT5113

220V转18V500mA非隔离恒压WT5113 亲爱的朋友们&#xff0c;你们是否在为如何提高电源方案而烦恼呢&#xff1f;今天我给大家带来了一款芯片&#xff0c;WT5113宽输出范围非隔离交直流转换芯片&#xff0c;它可是电源方案中的得力助手哦&#xff01; 这款芯片拥有220V降12V、2…

Mujoco210和Mujoco-py在 Ubuntu22.04 下的安装

mujoco和mujoco-py的关系&#xff1a;mujoco是一个物理引擎&#xff0c;主要应用于强化学习和最优化控制领域。mujoco-py是mujoco编程的 Python 接口&#xff0c;由OpenAI Gym开发&#xff0c;可以使用mujoco_py方便地调用mujoco的API。 mujoco官网&#xff1a; https://mujoco…

国产中间件概述

1、什么是中间件? 1.1、基本概念 定义:中间件,英文名为 Middleware,是独立的系统级软件,连接操作系统层和应用程序层,将不同操作系统提供应用的接口标准化、协议统一化,屏蔽具体操作的细节。位置:居于各类应用与操作系统之间,在操作系统、网络和数据库之上,应用软件…

Linux(openEuler、CentOS8)企业内网主备DNS服务器搭建

本实验环境为openEuler系统<以server方式安装>&#xff08;CentOS类似&#xff0c;可参考本文&#xff09; 知识点 什么是DNS&#xff1a;DNS服务器&#xff0c;即域名服务器&#xff08;Domain Name Server&#xff09;&#xff0c;是进行域名和与之相对应的IP地址转换…

24年最新AI数字人简单混剪

24年最新AI数字人简单混剪 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x 提取码&#xff1a;0b8x

2024年如何下载51cto的视频

你是否对学习新的技术知识感到困惑&#xff1f;是否在寻找一个优质的在线学习平台&#xff1f;那么&#xff0c;我告诉你一个秘密——51cto视频平台&#xff01;它是一个专注于技术领域的视频平台&#xff0c;提供了大量的高质量视频资源。如果你想在2024年下载51cto的视频&…

白酒:白酒香型与历史文化传承的关联性研究

云仓酒庄的豪迈白酒作为中国白酒的品牌&#xff0c;其香型与历史文化传承之间存在着紧密的关联。白酒的香型不仅是酿造技艺的体现&#xff0c;更是中华历史文化的重要组成部分。 首先&#xff0c;白酒的香型与中国的地理、气候和自然资源密切相关。不同地区的白酒产区&#xff…

用脚本写一个日期样式的字符

现在想要诸如此类样式的语句&#xff1a;&#xff08;过去三个月的&#xff09; 可以用python脚本写&#xff1a; from datetime import date, timedelta# 获取当前日期 current_date date.today()# 定义过去三个月的时间间隔 three_months_ago current_date - timedelta(da…

QT+多线程编程

QT的多线程编程有两种 1、自定义类继承QThread 第一种是自定义一个类继承于QThread&#xff0c;重写run()方法来实现。然后当需要使用线程的时候你就新建一个自定义对象&#xff0c;然后调用start方法开始运行。 下面的例子是widget里面创建一个线程&#xff0c;然后调用sta…

BGP协议应用:SW1、SW2、SW3、RT1、RT2之间运行BGP协议

8.SW1、SW2、SW3、RT1、RT2之间运行BGP协议,SW1、SW2、RT1 AS号65001、RT2 AS号65002、SW3 AS号65003。 (1)SW1、SW2、SW3、RT1、RT2之间通过Loopback1建立IPv4 BGP邻居。SW1和SW2之间财务通过Loopback2建立IPv4 BGP邻居,SW1和SW2的Loopback2互通采用静态路由。 (2)SW1…