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

【Spring】bean的生命周期

在这里插入图片描述
在这里插入图片描述

这里写目录标题

  • 1. 在类中提供生命周期控制方法,并在配置文件中配置init-method&destroy-method(配置)
    • 关闭容器操作1:ctx.close()
    • 关闭容器操作2:关闭钩子:ctx.registerShutdownHook()
  • 2. 实现接口来做和init和destroy(接口)
  • 3. bean的生命周期
  • 4. bean的销毁时机

1. 在类中提供生命周期控制方法,并在配置文件中配置init-method&destroy-method(配置)

定义实现类如下:

package com.example.demo231116.dao.impl;import com.example.demo231116.dao.BookDao;public class BookDaoImpl implements BookDao {public void save(){System.out.println("book dao save...");}public void init(){System.out.println("book dao init...");}public void destroy(){System.out.println("book dao destroy...");}
}

配置方法如下:

<bean id="bookDaoCycle" class="com.example.demo231116.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy" />

最终调用跟平时一样:

// IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao5 = (BookDao) ctx.getBean("bookDaoCycle");
System.out.println(bookDao5);

输出结果为:

book dao init...
com.example.demo231116.dao.impl.BookDaoImpl@5dd6264

关闭容器操作1:ctx.close()

并没有自动调用destroy方法,因为在程序执行结束后,java虚拟机关闭,程序不会自动调用destroy方法,如果需要调用,可以在程序的末尾加上:ctx.close(),即在java虚拟机关闭之前执行destroy方法
但是事实上,ApplicationContext 并没有close方法, ApplicationContext 下的一个接口才有定义close方法,所以这里想要使用close方法,可以修改IoC容器定义:ClassPathXmlApplicationContextctx = new ClassPathXmlApplicationContext("applicationContext.xml");
然后再末尾调用ctx.close():

// IoC容器
ClassPathXmlApplicationContextctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao5 = (BookDao) ctx.getBean("bookDaoCycle");
System.out.println(bookDao5);ctx.close()

输出结果为:

book dao init...
com.example.demo231116.dao.impl.BookDaoImpl@5dd6264
book dao destroy...

但是如果是这样的话,ctx.close()只能在程序的末尾写,因为在开头定义结束就写的话,这个IoC容器就被销毁了,下面也不可能执行一些getBean的操作

关闭容器操作2:关闭钩子:ctx.registerShutdownHook()

我们可以注册一个关闭钩子,在不用强行关闭IoC容器的情况下,设置在java虚拟机关闭之前让程序执行销毁的方法:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.registerShutdownHook();BookDao bookDao5 = (BookDao) ctx.getBean("bookDaoCycle");
System.out.println(bookDao5);

这样就不再需要强硬地执行ctx.close()方法了
:我在写这些代码的过程中发现一个老师没有提及的点,也是我之前一直忽略的,这些init方法的执行,是在初始化IoC容器时候就执行了,我的完整代码如下:

package com.example.demo231116;import com.example.demo231116.dao.BookDao;
import com.example.demo231116.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Demo231116Application2 {public static void main(String[] args) {// 3. 获取IoC容器ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");ctx.registerShutdownHook();// 4. 获取bean
//        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//        bookDao.save();BookService bookService = (BookService) ctx.getBean("bookService");bookService.save();BookDao bookDao = (BookDao) ctx.getBean("dao");BookDao bookDao1 = (BookDao) ctx.getBean("dao");System.out.println(bookDao);System.out.println(bookDao1);BookDao bookDao2 = (BookDao) ctx.getBean("bookDaoFactory");System.out.println(bookDao2);BookDao bookDao3 = (BookDao) ctx.getBean("bd");System.out.println(bookDao3);BookDao bookDao4 = (BookDao) ctx.getBean("bookDaoFactoryMethod");System.out.println(bookDao4);BookDao bookDao5 = (BookDao) ctx.getBean("bookDaoCycle");System.out.println(bookDao5);//        ctx.close();}
}

得到的结果是这样的:

Factory method....
实例工厂方法...
book dao init...
book service save...
book dao save...
com.example.demo231116.dao.impl.BookDaoImpl@6193932a
com.example.demo231116.dao.impl.BookDaoImpl@6193932a
com.example.demo231116.dao.impl.BookDaoImpl@647fd8ce
com.example.demo231116.dao.impl.BookDaoImpl@159f197
com.example.demo231116.dao.impl.BookDaoImpl@78aab498
com.example.demo231116.dao.impl.BookDaoImpl@5dd6264
book dao destroy...

事实上,init方法是在IoC容器初始化的时候执行了,而不是在我具体调用getBean()的时候才运行的,默认bean是单例模式,一开始就把init()给执行掉了
如果我不使用单例而是定义多例的scope:

<bean id="bookDaoCycle" class="com.example.demo231116.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy" scope="prototype" />

主代码如下:

package com.example.demo231116;import com.example.demo231116.dao.BookDao;
import com.example.demo231116.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Demo231116Application2 {public static void main(String[] args) {// 3. 获取IoC容器ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");ctx.registerShutdownHook();// 4. 获取bean
//        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//        bookDao.save();BookService bookService = (BookService) ctx.getBean("bookService");bookService.save();BookDao bookDao = (BookDao) ctx.getBean("dao");BookDao bookDao1 = (BookDao) ctx.getBean("dao");System.out.println(bookDao);System.out.println(bookDao1);BookDao bookDao2 = (BookDao) ctx.getBean("bookDaoFactory");System.out.println(bookDao2);BookDao bookDao3 = (BookDao) ctx.getBean("bd");System.out.println(bookDao3);BookDao bookDao4 = (BookDao) ctx.getBean("bookDaoFactoryMethod");System.out.println(bookDao4);BookDao bookDao5 = (BookDao) ctx.getBean("bookDaoCycle");BookDao bookDao6 = (BookDao) ctx.getBean("bookDaoCycle");System.out.println(bookDao5);System.out.println(bookDao6);//        ctx.close();}
}

这样运行的结果是:

Factory method....
实例工厂方法...
book service save...
book dao save...
com.example.demo231116.dao.impl.BookDaoImpl@d4342c2
com.example.demo231116.dao.impl.BookDaoImpl@d4342c2
com.example.demo231116.dao.impl.BookDaoImpl@2bbf180e
com.example.demo231116.dao.impl.BookDaoImpl@163e4e87
com.example.demo231116.dao.impl.BookDaoImpl@56de5251
book dao init...
book dao init...
com.example.demo231116.dao.impl.BookDaoImpl@78aab498
com.example.demo231116.dao.impl.BookDaoImpl@5dd6264

是在具体定义实例的时候才执行的init方法,所以scope不同,init方法执行的先后顺序是不一样的

2. 实现接口来做和init和destroy(接口)

只需要在bean类下多实现这两个接口:
并继承必要的方法:
在这里插入图片描述
定义代码如下:

package com.example.demo231116.dao.impl;import com.example.demo231116.dao.BookDao;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;public class BookDaoImpl implements BookDao, InitializingBean, DisposableBean {public void save(){System.out.println("book dao save...");}//    public void init(){
//        System.out.println("book dao init...");
//    }@Overridepublic void destroy() throws Exception {System.out.println("接口destroy");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("接口init");}
}

Spring Config配置如下:

<bean id="bookDaoCycle" class="com.example.demo231116.dao.impl.BookDaoImpl" />

这个afterPropertiesSet的init方法,是在先执行属性设置后再执行init方法

3. bean的生命周期

在这里插入图片描述

4. bean的销毁时机

在这里插入图片描述

相关文章:

【Spring】bean的生命周期

这里写目录标题 1. 在类中提供生命周期控制方法&#xff0c;并在配置文件中配置init-method&destroy-method&#xff08;配置&#xff09;关闭容器操作1&#xff1a;ctx.close()关闭容器操作2&#xff1a;关闭钩子&#xff1a;ctx.registerShutdownHook() 2. 实现接口来做和…...

C#运算符重载

运算符重载允许你重新定义内置运算符&#xff08;如、-、*等&#xff09;的行为&#xff0c;以便它们可以用于自定义类型&#xff08;类/结构体&#xff09;。通过运算符重载&#xff0c;你可以为自定义类型创建更直观和灵活的操作。 在C#中&#xff0c;可以重载的运算符如下&…...

【L2GD】: 无环局部梯度下降

文章链接&#xff1a;Federated Learning of a Mixture of Global and Local Models 发表期刊&#xff08;会议&#xff09;: ICLR 2021 Conference&#xff08;机器学习顶会&#xff09; 往期博客&#xff1a;FLMix: 联邦学习新范式——局部和全局的结合 目录 1.背景介绍2. …...

2023-11-14 LeetCode每日一题(阈值距离内邻居最少的城市)

2023-11-14每日一题 一、题目编号 1334. 阈值距离内邻居最少的城市二、题目链接 点击跳转到题目位置 三、题目描述 有 n 个城市&#xff0c;按从 0 到 n-1 编号。给你一个边数组 edges&#xff0c;其中 edges[i] [fromi, toi, weighti] 代表 fromi 和 toi 两个城市之间的…...

AdServices归因和iAd归因集成

AdServices framework 是 Apple 专门为 ASA 提供的归因框架 。尤其在ATT 政策推出以后&#xff0c;app 获取用户 IDFA 的比例大幅降低&#xff0c;传统的依靠IDFA 的方法也无法准确归因。 但是 Apple 为 ASA 开了一个后门&#xff0c;其他广告渠道无法获取用户的 IDFA 作为身份…...

关于 内部类 你了解多少?(详解!!)

目录 1. 什么是内部类&#xff1f; 2. 内部类的分类 3. 内部类 3.1 实例内部类 3.2 静态内部类 4. 局部内部类 5. 匿名内部类 6.对象的打印 “不积跬步无以至千里&#xff0c;不积小流无以成江海。”每天坚持学习&#xff0c;哪怕是一点点&#xff01;&#xff01;&a…...

CNVD-2021-09650:锐捷NBR路由器(guestIsUp.php)RCE漏洞复现 [附POC]

文章目录 锐捷NBR路由器guestIsUp.php远程命令执行漏洞(CNVD-2021-09650)复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 锐捷NBR路由器guestIsUp.php远程命令执行漏洞(CNVD-2021-09650)复现 [附POC] 0x01 前言 免…...

如何在Docker部署Draw.io绘图工具并远程访问

文章目录 前言1. 使用Docker本地部署Drawio2. 安装cpolar内网穿透工具3. 配置Draw.io公网访问地址4. 公网远程访问Draw.io 前言 提到流程图&#xff0c;大家第一时间可能会想到Visio&#xff0c;不可否认&#xff0c;VIsio确实是功能强大&#xff0c;但是软件为收费&#xff0…...

Android APK打包的过程主要步骤

Android APK打包的过程可以概括为以下几个主要步骤&#xff1a; 编译源代码&#xff1a;将开发好的Java源代码编译成Dalvik字节码文件&#xff08;.dex文件&#xff09;&#xff0c;Android安卓该文件包含了Android平台上的运行程序的指令集。打包资源文件&#xff1a;将应用程…...

吃透 Spring 系列—MVC部分

目录 ◆ SpringMVC简介 - SpringMVC概述 - SpringMVC快速入门 - Controller中访问容器中的Bean - SpringMVC关键组件浅析 ◆ SpringMVC的请求处理 - 请求映射路径的配置 - 请求数据的接收 - Javaweb常用对象获取 - 请求静态资源 - 注解驱动 标签 ◆ SpringMV…...

Java面试题(每天10题)-------连载(32)

目录 设计模式篇 1、工厂方法模式&#xff08;利用创建同一接口的不同实例&#xff09;&#xff1a; 2、抽象工厂模式&#xff08;多个工厂&#xff09; 3、单例模式&#xff08;保证对象只有一个实例&#xff09; 4、原型模式&#xff08;对一个原型进行复制、克隆产生类…...

HDP集群Kafka开启SASLPLAINTEXT安全认证

hdp页面修改kafka配置 java代码连接kafka增加对应的认证信息 props.put("security.protocol","SASL_PLAINTEXT");props.put("sasl.mechanism","PLAIN");props.put("sasl.jaas.config","org.apache.kafka.common.securi…...

判断上颌下颌的stl模型坐标轴是否正常

文章目录 研究方向:如何判断?又如何纠正?如何判断?Demo实现:先判断一个遍历相关文件夹下的所有病例如何纠正?Demo相关知识点研究方向:如何判断?又如何纠正? 如何判断? 当然,我们不能以坐标的正负来判断 我们看到这个Bounding Box里面有stl模型的xyz三轴方向的最大值与最…...

C/C++---------------LeetCode第1189. “气球” 的最大数量

气球的最大数量 题目及要求统计法在main内使用 题目及要求 给你一个字符串 text&#xff0c;你需要使用 text 中的字母来拼凑尽可能多的单词 “balloon”&#xff08;气球&#xff09;。 字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 “ba…...

Arthas(阿尔萨斯)--(三)

目录 一、Arthas学习 1、class/classloader相关命令一 1、sc 2、sm 2、class/classloader相关命令二 1、jad 2、mc 3、redefine 三、class/classloader相关命令三 一、Arthas学习 Arthas(阿尔萨斯)--(一) Arthas(阿尔萨斯)--(二) 1、class/classloader相关命令一 …...

《变形监测与数据处理》笔记/期末复习资料(择期补充更新)

变形&#xff1a; 变形是物体在外来因素作用下产生的形状、大小及位置的变化&#xff08;随时间域和空间域的变化&#xff09;&#xff0c;它是自然界普遍存在的现象。 变形体&#xff1a; 一般包括工程建筑物、构筑物、大型机械设备以及其他自然和人工对象等。 变形体和变形…...

Linux:进程替换和知识整合

文章目录 进程程序替换替换原理进程替换的理解 环境变量与进程替换命令行解释器实现逻辑 进程程序替换 前面已经学习了子进程的创建&#xff0c;但是子进程的创建不管怎么说&#xff0c;都是父进程代码的一部分&#xff0c;那么实际上如果想要子进程执行新的程序呢&#xff1f…...

React组件在什么情况下会重新渲染

当我们使用React编写组件时&#xff0c;组件的重新渲染是一个重要的概念。重新渲染是指React组件在特定情况下会重新执行其渲染函数&#xff0c;更新用户界面以反映最新的数据。很多情况下&#xff0c;组件不必要的重新渲染会严重影响性能&#xff0c;所以要充分了解触发组件重…...

云ES容灾方案

一、ES集群可用性容灾 1.1 云ES集群可用性容灾(使用跨可用区实例) 云ES集群部署在三个可用区,单可用区故障,云ES集群依然可能对外提供服务;两个可用区故障,需要进行控制台切流(集群会自动切的选择主节点) 应用服务部署在二个可用区,单可用区故障,依然可对提供服务1.2 …...

Golang 中的 Context 包

简介 今天&#xff0c;我们将讨论 Go 编程中非常重要的一个主题&#xff1a;context 包。如果你现在觉得它很令人困惑&#xff0c;不用担心 — 在本文结束时&#xff0c;你将像专家一样处理 context&#xff01; 想象一下&#xff0c;你在一个主题公园&#xff0c;兴奋地准备…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...