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

SpringBean模块(一)定义如何创建生命周期

一、介绍

1、简介

在 Spring 框架中,Bean 是指由 Spring 容器 管理的 Java 对象。Spring 负责创建、配置和管理这些对象,并在应用程序运行时对它们进行依赖注入(Dependency Injection,DI)。

通俗地讲,Spring Bean 就是 Spring 容器中的一个组件,它可以是一个普通的 Java 类,但被 Spring 管理起来后,就称为 "Bean"。

2、核心特点

  • 由 Spring 容器管理

    Bean 的生命周期由 Spring 负责,不需要手动创建和销毁。
  • 通过依赖注入(DI)管理对象

    Spring 自动为 Bean 注入所需的依赖,减少代码耦合。
  • 可以是任何 Java 对象

    普通 Java 类、Service、Repository、Controller 都可以是 Spring Bean。

二、如何创建 Spring Bean

有几下几种方法:

1、自动扫描(使用 @Component及其派生注解

Spring 提供了一系列注解(@Component@Service@Repository@Controller),用于标识一个类是 Spring Bean:

见注解篇

Springbean(二)@Component及其派生注解自动注入(1)介绍和规范_component 注入-CSDN博客

Springbean(二)@Component及其派生注解自动注入(2)使用注意和加载问题-CSDN博客

(1)注册

@Component 让 Spring 在 类路径扫描(Component Scanning) 时自动发现该类并注册为 Bean。

import org.springframework.stereotype.Component;@Component // 让 Spring 扫描并管理这个类
public class MyBean {public void sayHello() {System.out.println("Hello, Spring Bean!");}
}
 (2)使用

使用 @Autowired 注入 Bean

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MyService {@Autowiredprivate MyBean myBean; // 依赖注入public void doSomething() {myBean.sayHello();}
}
2、手动注册 Bean(使用 @Bean

如果不能修改原始类(例如第三方库),可以使用 @Bean 方法在 @Configuration 类中手动注册。

(1)注册
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyConfig {@Beanpublic MyBean myBean() {return new MyBean(); // 手动创建 Bean}
}
(2)使用

  同上

3、传统方式(在 XML 配置中定义 Bean)

(1)注册

  Spring 也支持 XML 方式定义 Bean:

<bean id="myBean" class="com.example.MyBean"/>

(2)使用

然后在 Java 代码中获取 Bean:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean myBean = context.getBean(MyBean.class);

三、生命周期

1、概述
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;@Component
public class MyBean implements InitializingBean, DisposableBean {public MyBean() {System.out.println("1️⃣ Bean 实例化(Constructor 调用)");}// 依赖注入后执行@PostConstructpublic void postConstruct() {System.out.println("2️⃣ @PostConstruct 方法执行");}// 实现 InitializingBean 接口@Overridepublic void afterPropertiesSet() {System.out.println("3️⃣ afterPropertiesSet() 方法执行(InitializingBean)");}// Bean 可用阶段(业务方法)public void doSomething() {System.out.println("🚀 Bean 正在使用...");}// 销毁之前执行@PreDestroypublic void preDestroy() {System.out.println("4️⃣ @PreDestroy 方法执行");}// 实现 DisposableBean 接口@Overridepublic void destroy() {System.out.println("5️⃣ destroy() 方法执行(DisposableBean)");}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;@SpringBootApplication
public class BeanLifecycleApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(BeanLifecycleApplication.class, args);// 获取 Bean 并调用方法MyBean myBean = context.getBean(MyBean.class);myBean.doSomething();// 关闭 Spring 容器(触发 Bean 销毁)((SpringApplication) context).close();}
}

一句话总结:Spring 负责 Bean 生命周期,开发者可以在关键阶段自定义行为! 

(1)实例化(Instantiation)

 Spring 通过 new 反射创建 Bean 实例。

(2)属性填充(Populate Properties)

Spring 依赖注入,设置 Bean 的 @Autowired 或 XML 配置的属性;

(3)BeanPostProcessor#postProcessBeforeInitialization();
(4)初始化(Initialization)
  • 调用 InitializingBean#afterPropertiesSet()(如果实现了 InitializingBean

  • 调用 @PostConstruct 标注的方法(如果有)

(5)BeanPostProcessor#postProcessAfterInitialization()
(6)Bean 可用(In Use)
(7)销毁(Destruction)
  • 调用 @PreDestroy 标注的方法(如果有)

  • 调用 DisposableBean#destroy()(如果实现了 DisposableBean

  • XML 配置或 @Bean(destroyMethod="xxx") 自定义销毁方法

看下具体流程

1、创建前准备阶段

在这个阶段,Spring上下文和相关配置被解析,查找与Bean相关的配置内容,如`init-method`和`destory-method`,以及BeanFactoryPostProcessor等前置和后置处理。这些配置允许开发者在Bean加载过程中实现扩展机制。

2、实例化Bean

对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。

对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。

通过反射机制,Spring创建Bean的实例对象。在这个阶段,Spring会扫描和解析Bean声明的属性。

3、依赖注入阶段

实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 以及 通过BeanWrapper提供的设置属性的接口完成属性设置与依赖注入。

4、其他处理

4.1、处理Aware接口

Spring会检测该对象是否实现了xxxAware接口,通过Aware类型的接口,可以让我们拿到Spring容器的一些资源:

①如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,传入Bean的名字;
②如果这个Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
②如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
③如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文;

4.2、BeanPostProcessor前置处理:

如果想对Bean进行一些自定义的前置处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。

4.3、InitializingBean:

如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法。

4.4、init-method:

如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。

4.5、BeanPostProcessor后置处理:

如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;

以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。

5、DisposableBean:

当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法; 

6、destroy-method:

最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

以上生命周期包含两个重要的事件:初始化和销毁事件。初始化事件发生在Bean的属性赋值之后,在`init-method`操作之前,而销毁事件则发生在Bean在容器关闭时,内存释放之前。

2、生命周期回调方式

Spring 提供多种方式来定制 Bean 生命周期的行为:

(1)使用 @PostConstruct@PreDestroy(推荐)

推荐使用 @PostConstruct@PreDestroy,因为它们是标准 Java 注解,和 Spring 解耦。

  • @PostConstruct:Bean 初始化完成后执行

  • @PreDestroy:Bean 销毁前执行

@Component
public class MyBean {@PostConstructpublic void init() {System.out.println("Bean 初始化完成");}@PreDestroypublic void cleanup() {System.out.println("Bean 即将被销毁");}
}
(2)实现 InitializingBeanDisposableBean

Spring 提供了 InitializingBeanDisposableBean 两个接口,不推荐使用,因为这样会耦合 Spring 框架,影响代码的可移植性。

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.DisposableBean;@Component
public class MyBean implements InitializingBean, DisposableBean {@Overridepublic void afterPropertiesSet() {System.out.println("Bean 初始化 afterPropertiesSet()");}@Overridepublic void destroy() {System.out.println("Bean 销毁 destroy()");}
}
(3)使用 @Bean(initMethod, destroyMethod)

如果是通过 @Configuration 手动注册 Bean,可以使用 @BeaninitMethoddestroyMethod

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyConfig {@Bean(initMethod = "init", destroyMethod = "cleanup")public MyBean myBean() {return new MyBean();}
}class MyBean {public void init() {System.out.println("Bean 初始化(initMethod)");}public void cleanup() {System.out.println("Bean 销毁(destroyMethod)");}
}
(4)使用 BeanPostProcessor(高级用法)

如果需要在 Bean 初始化前后进行操作,可以使用 BeanPostProcessor,适用于 AOP、代理、动态增强等高级需求。

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;@Component
public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("🚀 BeanPostProcessor - 初始化前:" + beanName);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("✅ BeanPostProcessor - 初始化后:" + beanName);return bean;}
}
3、什么时候会触发 Bean 的销毁
  • 单例(Singleton)Bean:Spring 容器关闭时销毁

  • 多例(Prototype)Bean:Spring 不会 自动管理销毁,需要手动处理

  • Web 应用

    • request 作用域:HTTP 请求结束时销毁

    • session 作用域:Session 结束时销毁

    • application 作用域:Web 应用关闭时销毁

相关文章:

SpringBean模块(一)定义如何创建生命周期

一、介绍 1、简介 在 Spring 框架中&#xff0c;Bean 是指由 Spring 容器 管理的 Java 对象。Spring 负责创建、配置和管理这些对象&#xff0c;并在应用程序运行时对它们进行依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;。 通俗地讲&#xff0c;Sp…...

k8s存储介绍(六)StorangeClass

一、Kubernetes 存储类&#xff08;StorageClass&#xff09;详解 1. 什么是 StorageClass&#xff1f; 在 Kubernetes 中&#xff0c;StorageClass&#xff08;存储类&#xff09;是一种用于动态创建 PersistentVolume&#xff08;PV&#xff09;的资源对象。它允许管理员根…...

Redis-04.Redis常用命令-字符串常用命令

一.字符串操作命令 set name jack 点击左侧name&#xff0c;显示出值。 get name get abc&#xff1a;null setex key seconds value&#xff1a;设置过期时间&#xff0c;过期后该键值对将会被删除。 然后再get&#xff0c;在过期时间内可以get到&#xff0c;过期get不到。…...

golang接口-interface

interface接口 概述 接口&#xff08;interface&#xff09;是 Go 语言中的一种类型&#xff0c;用于定义行为的集合&#xff0c;它通过描述类型必须实现的方法&#xff0c;规定了类型的行为契约。 它把所有的具有共性的方法定义在一起&#xff0c;任何其他类型只要实现了这…...

Epub转PDF软件Calibre电子书管理软件

Epub转PDF软件&#xff1a;Calibre电子书管理软件 https://download.csdn.net/download/hu5566798/90549599 一款好用的电子书管理软件&#xff0c;可快速导入电脑里的电子书并进行管理&#xff0c;支持多种格式&#xff0c;阅读起来非常方便。同时也有电子书格式转换功能。 …...

【自学笔记】PHP语言基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. PHP 简介2. PHP 环境搭建3. 基本语法变量与常量数据类型运算符 4. 控制结构条件语句循环语句 5. 函数函数定义与调用作用域 6. 数组7. 字符串8. 表单处理9. 会话…...

FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读

FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读 论文下载论文翻译FAST-LIVO2: 快速、直接的LiDAR-惯性-视觉里程计摘要I 引言II 相关工作_直接方法__LiDAR-视觉&#xff08;-惯性&#xff09;SLAM_ III 系统概述IV 具有顺序状态更新的误差状态迭代卡尔曼滤波…...

【Git】--- Git远程操作 标签管理

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Git 前面我们学习的操作都是在本地仓库进行了&#xff0c;如果团队内多人协作都在本地仓库操作是不行的&#xff0c;此时需要新的解决方案 --- 远程仓库。…...

Docker学习之服务编排(day9)

文章目录 前言一、问题描述二、解决方案1.安装Docker Compose1.1 [github下载相应版本](https://github.com/docker/compose/releases)1.2 将下载的文件移动到 /usr/local/bin 目录&#xff0c;确保它能够被系统识别为可执行文件1.3 赋予执行权限1.4 验证安装1.5 创建软链 2. 使…...

前后端常见模型以及相关环境配置介绍

一、前端常见框架 Vue.js 特点&#xff1a;采用数据驱动的响应式编程&#xff0c;组件化的开发模式使得代码结构清晰&#xff0c;易于维护&#xff0c;且学习成本相对较低&#xff0c;适合初学者和快速迭代的项目。应用场景&#xff1a;广泛应用于各类 Web 应用开发&#xff…...

职能型组织、项目型组织、矩阵型组织的介绍及优缺点比较

PMP考试中&#xff0c;经常会涉及到职能型组织、项目型组织、矩阵型组织的比较&#xff0c;下面简单介绍下职能型组织、项目型组织、矩阵型组织及其优缺点&#xff1a; 一、职能型组织 定义&#xff1a;以专业职能划分部门&#xff08;如财务、技术、市场等&#xff09;&…...

Java基本类型深度解析:从内存模型到高效编程实践

Java基本类型深度解析&#xff1a;从内存模型到高效编程实践 一、Java基本类型概述 Java作为强类型语言&#xff0c;定义了8种基本数据类型&#xff08;Primitive Types&#xff09;&#xff0c;这些类型直接存储数据值而非对象引用&#xff0c;是构建Java程序的基础。它们的…...

论文阅读笔记——ST-4DGS,WideRange4D

ST-4DGS ST-4DGS 论文 在 4DGS 中&#xff0c;变形场 F \mathcal{F} F 与运动参数 X 和形状参数 ( S , R ) (S,R) (S,R) 高度耦合&#xff0c;导致训练时高斯表示紧凑型退化&#xff0c;影响动态渲染质量。由此&#xff0c;本文提出两种方法解耦运动与形状参数&#xff0c;保…...

[python]基于yolov8实现热力图可视化支持图像视频和摄像头检测

YOLOv8 Grad-CAM 可视化工具 本工具基于YOLOv8模型&#xff0c;结合Grad-CAM技术实现目标检测的可视化分析&#xff0c;支持图像、视频和实时摄像头处理。 功能特性 支持多种Grad-CAM方法实时摄像头处理视频文件处理图像文件处理调用简单 环境要求 Python 3.8需要电脑带有…...

五.ubuntu20.04 - ffmpeg推拉流以及Nginx、SRS本地部署

一.本地部署nginx 1.编译ffmpeg&#xff0c;参考这位博主的&#xff0c;编译选项有的enable找不到的不需要的可以直接删除&#xff0c;但是像sdl&#xff08;包含ffplay&#xff09;、h264、h265这些需要提前下载好&#xff0c;里面都有下载指令。 Ubuntu20.04 编译安装 FFmp…...

深度神经网络全解析:原理、结构与方法对比

深度神经网络全解析&#xff1a;原理、结构与方法对比 1. 引言 随着人工智能的发展&#xff0c;深度神经网络&#xff08;Deep Neural Network&#xff0c;DNN&#xff09;已经成为图像识别、自然语言处理、语音识别、自动驾驶等领域的核心技术。相比传统机器学习方法&#x…...

豪越科技消防一体化平台:打通消防管理“任督二脉”

在城市的车水马龙间&#xff0c;火灾隐患如潜藏的暗礁&#xff0c;威胁着人们的生命财产安全。传统消防管理模式在现代社会的复杂环境下&#xff0c;逐渐显露出诸多弊端。内部管理分散混乱&#xff0c;人员、装备、物资管理缺乏统一标准和高效流程&#xff1b;外部监管困难重重…...

【Matlab】-- 基于MATLAB的美赛常用多种算法

文章目录 文章目录 01 内容概要02 各种算法基本原理03 部分代码04 代码下载 01 内容概要 本资料集合了多种数学建模和优化算法的常用代码资源&#xff0c;旨在为参与美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff0c;简称美赛&#xff09;的参赛者提供实用的编程工具和…...

机器学习课程

前言 课程代码和数据文件&#xff1a; 一、机器学习概述 1.1.人工智能概述 机器学习和人工智能&#xff0c;深度学习的关系 机器学习是人工智能的一个实现途径深度学习是机器学习的一个方法发展而来 达特茅斯会议-人工智能的起点 1956年8月&#xff0c;在美国汉诺斯小镇宁静…...

AIGC(生成式AI)试用 28 -- 跟着清华教程学习 - AIGC发展研究 3.0

目标&#xff1a;继续学习 - 信息不对称、不平等、隐私泄露和数据滥用 - 问、改、创、优 - “概率预测&#xff08;快速反应&#xff09;”模型和“链式推理&#xff08;慢速思考&#xff09;”模型 - 思维滞环现象解决思路&#xff1a;1.调整提问&#xff1a;改变问题方式&…...

问题:md文档转换word,html,图片,excel,csv

文章目录 问题&#xff1a;md文档转换word&#xff0c;html&#xff0c;图片&#xff0c;excel&#xff0c;csv&#xff0c;ppt**主要职责****技能要求****发展方向****学习建议****薪资水平** 方案一&#xff1a;AI Markdown内容转换工具打开网站md文档转换wordmd文档转换pdfm…...

【Java】面向对象之static

用static关键字修饰成员变量 有static修饰成员变量&#xff0c;说明这个成员变量是属于类的&#xff0c;这个成员变量称为类变量或者静态成员变量。 直接用 类名访问即可。因为类只有一个&#xff0c;所以静态成员变量在内存区域中也只存在一份。所有的对象都可以共享这个变量…...

解决:在运行 plt.show()`时,程序会等待你手动关闭图片窗口才能继续往下执行

你这个问题本质是&#xff1a; 在运行 plt.show() 时&#xff0c;程序会等待你手动关闭图片窗口才能继续往下执行。 这其实是 matplotlib 的默认行为 —— 它会弹出一个交互式窗口让你“看完图再走”。 ✅ 为什么会这样&#xff1f; 你在程序中使用了&#xff1a; import mat…...

Anaconda安装-Ubuntu-Linux

1、进入Anaconda官网&#xff0c;以下载最新版本&#xff0c;根据自己的操作系统选择适配的版本。 2、跳过注册&#xff1a; 3、选择适配的版本&#xff1a; 4、cd ~/anaconda_download 5、bash Anaconda3-2024.10-1-Linux-x86_64.sh 6、按Enter或PgDn键滚动查看协议&…...

Linux 配置NFS服务器

1. 开放/nfs/shared目录&#xff0c;供所有用户查阅资料 服务端 &#xff08;1&#xff09;安装nfs服务&#xff0c;nfs-utils包中包含rpcbind&#xff08;rpc守护进程&#xff09; [rootnode1-server ~]# yum install -y nfs-utils # nfs-utils包中包含rpcbind [rootnode…...

css100个问题

一、基础概念 CSS的全称及作用是什么&#xff1f;行内样式、内部样式表、外部样式表的优先级&#xff1f;解释CSS的层叠性&#xff08;Cascading&#xff09;CSS选择器优先级计算规则伪类与伪元素的区别&#xff1f;举例说明!important的作用及使用注意事项如何继承父元素字体…...

塔能科技:用精准节能撬动社会效益的行业杠杆

在全球积极践行可持续发展理念的当下&#xff0c;能源高效利用与节能减排&#xff0c;已然成为各行各业实现高质量发展绕不开的关键命题。对企业来说&#xff0c;节能早已不是一道可做可不做的选择题&#xff0c;而是关乎生存与发展、社会责任与竞争力的必答题。塔能科技推出的…...

Java 大视界 -- Java 大数据在自动驾驶高精度地图数据更新与优化中的技术应用(157)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

Conda配置Python环境

1. 安装 Conda 选择发行版&#xff1a; Anaconda&#xff1a;适合需要预装大量科学计算包的用户&#xff08;体积较大&#xff09;。 Miniconda&#xff1a;轻量版&#xff0c;仅包含 Conda 和 Python&#xff08;推荐自行安装所需包&#xff09;。 验证安装&#xff1a; co…...

nginx https配置

一.https配置 HTTPS 协议是由HTTP 加上TLS/SSL 协议构建的可进行加密传输、身份认证的网络协议&#xff0c;主要通过数字证书、加密算法、非对称密钥等技术完成互联网数据传输加密&#xff0c;实现互联网传输安全保护。 1.生成证书 openssl genrsa -des3 -out server.key 20…...