Spring Bean生命周期

Bean生命周期:

  1. 创建 Bean 的实例:Bean 容器首先会找到配置文件中的 Bean 定义,然后使用 Java 反射 API 来创建 Bean 的实例。

  2. Bean 属性赋值/填充:为 Bean 设置相关属性和依赖,例如@Autowired 等注解注入的对象、@Value 注入的值、setter方法或构造函数注入依赖和值、@Resource注入的各种资源。

  3. Bean 初始化

    Aware 接口能让 Bean 能拿到 Spring 容器资源。

    • 如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName()方法,传入 Bean 的名字。
    • 如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoader对象的实例。
    • 如果 Bean 实现了 BeanFactoryAware 接口,调用 setBeanFactory()方法,传入 BeanFactory对象的实例。
    • 与上面的类似,如果实现了其他 *.Aware接口,就调用相应的方法。
    • 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
    • 如果 Bean 实现了InitializingBean接口,执行afterPropertiesSet()方法。
    • 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。或者,也可以直接通过@PostConstruct 注解标记 Bean 初始化执行的方法。
    • 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法。
  4. 销毁 Bean:销毁并不是说要立马把 Bean 给销毁掉,而是把 Bean 的销毁方法先记录下来,将来需要销毁 Bean 或者销毁容器的时候,就调用这些方法去释放 Bean 所持有的资源。

    • 如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
    • 如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的 Bean 销毁方法。或者,也可以直接通过@PreDestroy 注解标记 Bean 销毁之前执行的方法。

Bean生命周期流程如图所示:

在这里插入图片描述

代码测试:

package com.spring.demo.liftcycle;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;@Component
@Slf4j
// public class User {
public class User implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {public User() {log.info("User的构造方法执行了.........");}private String name;@Value(value = "张三")public void setName(String name) {log.info("BeanNameAware-setName方法执行了.........");}@Overridepublic void setBeanName(String name) {log.info("setBeanName方法执行了.........");}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {log.info("BeanFactoryAware-setBeanFactory方法执行了.........");}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {log.info("ApplicationContextAware-setApplicationContext方法执行了........");}@PostConstructpublic void selfInit() {log.info("自定义init方法执行了.................");}@Overridepublic void afterPropertiesSet() throws Exception {log.info("InitializingBean-afterPropertiesSet方法执行了........");}@PreDestroypublic void selfDestory() {log.info("自定义destory方法执行了...............");}@Overridepublic void destroy() throws Exception {log.info("DisposableBean-destroy方法执行........");}
}
package com.spring.demo.liftcycle;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;@Component
public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals("user")) {System.out.println("postProcessBeforeInitialization方法执行了->user对象初始化方法前开始增强....");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals("user")) {System.out.println("postProcessAfterInitialization->user对象初始化方法后开始增强....");//cglib代理对象Enhancer enhancer = new Enhancer();//设置需要增强的类enhancer.setSuperclass(bean.getClass());//执行回调方法,增强方法enhancer.setCallback(new InvocationHandler() {@Overridepublic Object invoke(Object o, Method method, Object[] objects) throws Throwable {//执行目标方法return method.invoke(method,objects);}});//创建代理对象return enhancer.create();}return bean;}}

日志输出:

2024-07-04 21:54:20.649  INFO 256748 --- [           main] com.spring.demo.liftcycle.User           : User的构造方法执行了.........
2024-07-04 21:54:20.652  INFO 256748 --- [           main] com.spring.demo.liftcycle.User           : BeanNameAware-setName方法执行了.........
2024-07-04 21:54:20.652  INFO 256748 --- [           main] com.spring.demo.liftcycle.User           : setBeanName方法执行了.........
2024-07-04 21:54:20.652  INFO 256748 --- [           main] com.spring.demo.liftcycle.User           : BeanFactoryAware-setBeanFactory方法执行了.........
2024-07-04 21:54:20.653  INFO 256748 --- [           main] com.spring.demo.liftcycle.User           : ApplicationContextAware-setApplicationContext方法执行了........
postProcessBeforeInitialization方法执行了->user对象初始化方法前开始增强....
2024-07-04 21:54:20.653  INFO 256748 --- [           main] com.spring.demo.liftcycle.User           : 自定义init方法执行了.................
2024-07-04 21:54:20.653  INFO 256748 --- [           main] com.spring.demo.liftcycle.User           : InitializingBean-afterPropertiesSet方法执行了........
postProcessAfterInitialization->user对象初始化方法后开始增强....
2024-07-04 21:54:20.655  INFO 256748 --- [           main] com.spring.demo.liftcycle.User           : User的构造方法执行了.........
2024-07-04 21:54:20.912  INFO 256748 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2024-07-04 21:54:20.918  INFO 256748 --- [           main] com.spring.demo.SpringDemoApplication    : Started SpringDemoApplication in 2.011 seconds (JVM running for 2.649)Disconnected from the target VM, address: '127.0.0.1:4158', transport: 'socket'
2024-07-04 21:54:30.871  INFO 256748 --- [ionShutdownHook] com.spring.demo.liftcycle.User           : 自定义destory方法执行了...............
2024-07-04 21:54:30.872  INFO 256748 --- [ionShutdownHook] com.spring.demo.liftcycle.User           : DisposableBean-destroy方法执行........Process finished with exit code 130

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

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

相关文章

强强联合!当RAG遇到长上下文,滑铁卢大学发布LongRAG,效果领先GPT-4 Turbo 50%

过犹不及——《论语先进》 大学考试时,有些老师允许带备cheet sheet(忘纸条),上面记着关键公式和定义,帮助我们快速作答提高分数。传统的检索增强生成(RAG)方法也类似,试图找出精准的知识片段来辅助大语言模型(LLM)。 但这种方法其实有问题…

React@16.x(48)路由v5.x(13)源码(5)- 实现 Switch

目录 1&#xff0c;原生 Switch 的渲染内容2&#xff0c;实现 1&#xff0c;原生 Switch 的渲染内容 对如下代码来说&#xff1a; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; function News() {return <div className"p…

MySQL体系架构

1.1.MySQL的分支与变种 MySQL变种有好几个&#xff0c;主要有三个久经考验的主流变种&#xff1a;Percona Server&#xff0c;MariaDB和 Drizzle。它们都有活跃的用户社区和一些商业支持&#xff0c;均由独立的服务供应商支持。同时还有几个优秀的开源关系数据库&#xff0c;值…

JVM专题之Java对象内存模型

一个Java对象在内存中包括3个部分: 对象头、实例数据和对齐填充 数据 内存 -- CPU 寄存器 -127 补码 10000001 - 11111111 32位的处理器 一次能够去处理32个二进制位 4字节的数据 64位操作系统 8字节 2的64次方的寻址空间 指针压缩…

从零开始:大模型简介与应用|实战系列

实战系列 相信有不少伙伴对大模型有所耳闻&#xff0c;但也是一知半解&#xff0c;也许你知道很重要可以为自己的工作提供帮助但是不知道该如何结合&#xff0c;又或是转行的过程中并不知道从何入手&#xff0c;网上的教程要么不包含具体的操作步骤要么需要好几篇合在一起才能…

鸿蒙小案例-首选项工具类

一个简单的首选项工具类 主要提供方法 初始化 init()方法建议在EntryAbility-》onWindowStageCreate 方法中使用 没多少东西&#xff0c;放一下测试代码 import { PrefUtil } from ./PrefUtil; import { promptAction } from kit.ArkUI;Entry Component struct PrefIndex {St…

在window上搭建docker

1、打开Hyper-V安装 在地址栏输入控制面板&#xff0c;然后回车 勾选Hyper-V安装&#xff0c;如果没有找到Hyper-V&#xff0c;那么请走第2步 2、如果没有Hyper-V(可选&#xff09;第一步无法打开 家庭版本需要开启Hyper-V 创建一个文本文档&#xff0c;后缀名称为.bat.名称…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【密钥生成介绍及算法规格】

密钥生成介绍及算法规格 当业务需要使用HUKS生成随机密钥&#xff0c;并由HUKS进行安全保存时&#xff0c;可以调用HUKS的接口生成密钥。 注意&#xff1a; 密钥别名中禁止包含个人数据等敏感信息。 开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harm…

【C++】 ——【模板初阶】——基础详解

目录 1. 泛型编程 1.1 泛型编程的概念 1.2 泛型编程的历史与发展 1.3 泛型编程的优势 1.4 泛型编程的挑战 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 2.6 函数模板的特化 2.7 函数模板的使…

html+css+js淘宝商品界面

点击商品&#xff0c;alert弹出商品ID 图片使用了占位符图片&#xff0c;加载可能会慢一点 你可以把它换成自己的图片&#x1f603;源代码在图片后面 效果图 源代码 <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8"…

时空预测+特征分解!高性能!EMD-Transformer和Transformer多变量交通流量时空预测对比

时空预测特征分解&#xff01;高性能&#xff01;EMD-Transformer和Transformer多变量交通流量时空预测对比 目录 时空预测特征分解&#xff01;高性能&#xff01;EMD-Transformer和Transformer多变量交通流量时空预测对比效果一览基本介绍程序设计参考资料 效果一览 基本介绍…

番外篇 | YOLOv8改进之即插即用全维度动态卷积ODConv + 更换Neck网络为GFPN

前言:Hello大家好,我是小哥谈。本文所做出的改进是在YOLOv8中引入即插即用全维度动态卷积ODConv和更换Neck网络为GFPN,希望大家学习之后能够有所收获~!🌈 目录 🚀1.基础概念 🚀2.网络结构 🚀3.添加步骤 🚀4.改进方法 🍀🍀步骤1:block.py文件修改…

在TkinterGUI界面显示WIFI网络摄像头(ESP32s3)视频画面

本实验结合了之前写过的两篇文章Python调用摄像头&#xff0c;实时显示视频在Tkinter界面以及ESP32 S3搭载OV2640摄像头释放热点&#xff08;AP&#xff09;工作模式–Arduino程序&#xff0c;当然如果手头有其他可以获得网络摄像头的URL即用于访问摄像头视频流的网络地址&…

解析MySQL核心技术:视图的实用指南与实践案例

在数据库管理中&#xff0c;MySQL视图&#xff08;View&#xff09;是一种强大的功能&#xff0c;利用它可以简化复杂查询、提高数据安全性以及增强代码的可维护性。本篇文章将详细介绍MySQL视图的相关知识&#xff0c;包括视图的创建、修改、删除、使用场景以及常见的最佳实践…

Python学生信息管理系统(完整代码)

引言&#xff1a;&#xff08;假装不是一个大学生课设&#xff09;在现代教育管理中&#xff0c;学生管理系统显得尤为重要。这种系统能够帮助教育机构有效地管理学生资料、成绩、出勤以及其他教育相关活动&#xff0c;从而提高管理效率并减少人为错误。通过使用Python&#xf…

亚马逊跟卖选品erp采集,跟卖卖家的选品利器,提升选品效率!

今天给亚马逊跟卖卖家&#xff0c;分享我现在在用的两种选品方式&#xff0c;做个铺货或者是跟卖都可以&#xff0c;是不是很多卖家选品现在都是亚马逊前端页面或是新品榜单选择产品跟卖&#xff0c;这样找品这就相当于大海捞针&#xff0c;而且新品榜单的产品你能看到那其他卖…

经典卷积神经网络 LeNet

一、实例图片 #我们传入的是28*28&#xff0c;所以加了padding net nn.Sequential(nn.Conv2d(1, 6, kernel_size5, padding2), nn.Sigmoid(),nn.AvgPool2d(kernel_size2, stride2),nn.Conv2d(6, 16, kernel_size5), nn.Sigmoid(),nn.AvgPool2d(kernel_size2, stride2),nn.Flat…

Linux Swap机制关键点分析

1. page被swap出去之后,再次缺页是怎么找到找个换出的页面? 正常内存的页面是通过pte映射找到page的,swap出去的page有其特殊的方式:swap的页面page->private字段保存的是:swap_entry_t通过swap_entry_t就能找到该页面的扇区号sector_t,拿到扇区号就可以从块设备中读…

day04-组织架构

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.组织架构-树组件应用树形组件-用层级结构展示信息&#xff0c;可展开或折叠。 2.组织架构-树组件自定义结构3.组织架构-获取组织架构数据4.组织架构-递归转化树形…