Spring-Bean 生命周期

news/2024/9/18 12:27:18/ 标签: spring, java, 后端

Spring 是一个强大的 Java 框架,广泛应用于企业级应用开发中。Spring 框架的核心是它的依赖注入机制(DI),而 Bean 是 DI 的基本单位。在 Spring 中,Bean 的生命周期从创建到销毁,涉及多个阶段和机制

一、Spring Bean 的概念

在 Spring 框架中,Bean 是由 Spring IoC 容器管理的对象。简单来说,Bean 是由容器创建、初始化、使用和销毁的组件。在一个典型的 Spring 应用中,Bean 定义了应用的业务逻辑、数据库连接、配置属性等核心组件。

Spring IoC 容器负责管理 Bean 的生命周期,容器根据 Bean 的配置决定何时实例化 Bean、何时初始化、何时销毁 Bean 等。

二、Spring Bean 的生命周期概述

Spring Bean 生命周期可以分为以下几个阶段:

  1. 实例化(Instantiation):Spring 容器根据 Bean 配置实例化 Bean 对象。
  2. 属性赋值(Populate properties):Spring 容器将配置文件或注解中定义的属性值注入到 Bean 的各个字段中。
  3. 初始化(Initialization):在属性注入完成后,Spring 容器调用相关回调方法来完成初始化工作。
  4. 使用(Usage):Bean 被容器管理和客户端调用,提供业务逻辑服务。
  5. 销毁(Destruction):当容器关闭时,Spring 负责销毁 Bean,释放资源。

每个阶段都可以通过各种回调和配置来自定义 Bean 的行为,确保 Bean 能够满足具体应用场景的需求。

三、Bean 生命周期的详细流程

3.1 实例化(Instantiation)

Bean 的生命周期从实例化开始。当容器启动时,Spring IoC 容器根据配置文件(XML 或 Java 注解)中的定义,利用反射机制实例化 Bean 对象。通常情况下,Spring 使用无参构造函数来创建 Bean,但也可以通过构造函数注入创建 Bean。

例如,下面是一个简单的 Bean 配置:

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

在实例化阶段,Spring 会根据 com.example.MyBean 类,使用反射创建其对象。

3.2 属性赋值(Populate Properties)

实例化完成后,Spring 开始为 Bean 设置属性。Spring 通过依赖注入(Dependency Injection, DI)机制将配置文件中的属性值或者其他 Bean 注入到新实例化的 Bean 中。

Spring 支持两种方式为 Bean 注入属性:

  1. 构造器注入:通过 Bean 的构造函数注入依赖。
  2. Setter 方法注入:通过 Setter 方法注入依赖。

例如,通过 XML 文件进行属性赋值:

<bean id="myBean" class="com.example.MyBean"><property name="name" value="Spring Bean"/>
</bean>

这里,name 属性会通过 setName 方法注入到 MyBean 对象中。

3.3 初始化(Initialization)

在完成属性赋值后,Bean 进入初始化阶段。在这个阶段,Bean 可以执行一些自定义的初始化逻辑,例如打开数据库连接、加载资源等。

Spring 提供了多种方式自定义初始化逻辑:

  1. 实现 InitializingBean 接口:Bean 可以实现该接口的 afterPropertiesSet() 方法来自定义初始化逻辑。
  2. 指定 init-method:在 XML 配置文件中,可以为 Bean 指定一个初始化方法,Spring 容器会在初始化时调用这个方法。
  3. 使用 @PostConstruct 注解:在 Bean 类的方法上添加该注解,Spring 容器会在 Bean 初始化时调用该方法。

例如,使用 init-method

<bean id="myBean" class="com.example.MyBean" init-method="init"/>
java">public class MyBean {public void init() {// 自定义初始化逻辑System.out.println("Bean is initialized.");}
}
3.4 使用(Usage)

Bean 初始化完成后,进入使用阶段。在这个阶段,Bean 开始为应用提供服务。Spring IoC 容器将 Bean 注入到需要的地方(例如,控制器、服务层、数据访问层),并在整个应用生命周期中管理其状态。

Bean 在这一阶段会被各种业务逻辑调用。例如,如果这是一个数据库连接 Bean,它会在应用程序的各个部分被使用来进行数据库查询。

3.5 销毁(Destruction)

当容器关闭时(例如,Spring 应用程序上下文关闭时),Spring 会调用 Bean 的销毁方法。销毁阶段是为了释放 Bean 占用的资源,比如关闭数据库连接、释放文件资源等。

类似于初始化阶段,Spring 提供了几种方式自定义销毁逻辑:

  1. 实现 DisposableBean 接口:Bean 可以实现该接口的 destroy() 方法,在容器销毁时被调用。
  2. 指定 destroy-method:在 XML 配置文件中为 Bean 指定一个销毁方法,Spring 会在容器销毁时调用该方法。
  3. 使用 @PreDestroy 注解:在方法上添加该注解,Spring 容器会在销毁 Bean 时调用该方法。

例如,使用 destroy-method

<bean id="myBean" class="com.example.MyBean" destroy-method="cleanup"/>
java">public class MyBean {public void cleanup() {// 自定义销毁逻辑System.out.println("Bean is destroyed.");}
}

需要注意的是,只有单例作用域(Singleton)的 Bean 会在容器关闭时销毁,而原型作用域(Prototype)的 Bean 不会被 Spring 容器管理销毁,开发者需要自行管理。

四、Spring 提供的 Bean 生命周期接口和注解

Spring 提供了一些接口和注解,帮助开发者更加灵活地管理 Bean 的生命周期。

4.1 InitializingBeanDisposableBean
  • InitializingBean:提供 afterPropertiesSet() 方法,允许在属性赋值完成后自定义初始化逻辑。
  • DisposableBean:提供 destroy() 方法,允许在容器销毁时执行清理操作。
4.2 @PostConstruct@PreDestroy
  • @PostConstruct:该注解用于标记在 Bean 初始化之后要执行的方法。它与 InitializingBeanafterPropertiesSet() 类似,但更加灵活且易于使用。
  • @PreDestroy:该注解用于标记在 Bean 销毁前要执行的方法,类似于 DisposableBeandestroy()
4.3 BeanPostProcessor 接口

BeanPostProcessor 是 Spring 提供的一个接口,它允许在 Bean 初始化前后执行一些额外的处理逻辑。通过实现 BeanPostProcessor,可以在 Bean 的整个生命周期过程中插入额外的逻辑,如监控或修改 Bean 实例。

  • postProcessBeforeInitialization():在 Bean 初始化之前执行。
  • postProcessAfterInitialization():在 Bean 初始化之后执行。

例如:

java">public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {System.out.println("Before Initialization: " + beanName);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("After Initialization: " + beanName);return bean;}
}

五、Spring Bean 生命周期的作用域

Spring 提供了几种 Bean 的作用域(scope),它们会影响 Bean 的生命周期:

  1. Singleton:在整个应用上下文中,只有一个实例。Spring 容器会管理其完整的生命周期。
  2. Prototype:每次请求时都会创建一个新的实例,容器不会管理其销毁。
  3. Request:每个 HTTP 请求创建一个新的 Bean 实例(适用于 Web 应用)。
  4. Session:每个 HTTP Session 创建一个新的 Bean 实例。
  5. Application:每个 ServletContext 创建一个新的 Bean 实例。

六、总结

Spring Bean 生命周期包含从实例化、属性赋值、初始化、使用到销毁的完整流程。通过使用 Spring 提供的各种接口和注解,开发者可以轻松地自定义 Bean 在不同阶段的行为。同时,Spring 提供了 BeanPostProcessor 等扩展机制,使得开发者可以在生命周期的各个阶段插入额外的逻辑。


http://www.ppmy.cn/news/1524503.html

相关文章

【Vue】状态管理模式Vuex

数据共享 流程搭建变更状态辅助函数分割模块 流程 Vuex是一个Vue的状态管理工具&#xff0c;状态就是数据&#xff08;某个状态在很多个组件来使用 &#xff0c;多个组件共同维护一份数据&#xff09; 搭建 1&#xff09;Vuex我们在脚手架搭建项目的时候直接搭建好了&#xff0…

Axios 掌握现代 Web 开发的 HTTP 客户端

Axios: 掌握现代 Web 开发的 HTTP 客户端 在现代 Web 开发中&#xff0c;与后端进行数据交互是不可或缺的一部分。Axios 是一个流行的基于 Promise 的 HTTP 客户端&#xff0c;它提供了一种简洁、高效的方式来发送异步请求。本文将引导初学者学会使用 Axios&#xff0c;并探讨…

Qt实现登录界面

本文基于Qt实现一个简单的登录界面&#xff0c;主要使用到Widget、button、edit等控件&#xff0c;基于自定义的信号槽实现界面的跳转&#xff0c;使用绘图设备添加背景图等。 1. 创建主界面 设计主界面的样式&#xff0c;并添加相关的控件。如下显示&#xff1a; 代码如下&…

python如何把数据导出生成pdf?

文章目录 前言介绍多种生成PDF的方法一、使用reportlab二、使用FPDF三、使用Pandas与pdfkit总结 前言介绍多种生成PDF的方法 在Python中&#xff0c;将数据导出并生成PDF文件&#xff0c;你可以使用多种库来实现&#xff0c;其中比较流行的有reportlab和FPDF&#xff08;针对简…

JavaScript中的控制流语句:break、continue、return、throw

在JavaScript编程中&#xff0c;控制流语句是控制代码执行流程的重要工具。这些语句包括break、continue、return和throw&#xff0c;它们可以在循环、函数以及其他代码块中使用&#xff0c;以改变正常的执行顺序。下面我们将逐一探讨这些语句的用途和示例。 break break语句…

echarts X轴文本太长 formatter自定义文本的显示方式

如果ECharts中X轴的文本太长&#xff0c;可以通过设置axisLabel的rotate属性来旋转标签&#xff0c;或者使用formatter函数来自定义文本的显示方式。另外&#xff0c;可以开启axisLabel的interval属性来控制显示的标签的间隔。 option {tooltip: {},xAxis: {type: category,d…

构建Vue项目的侧边栏组件:Aside

构建Vue项目的侧边栏组件&#xff1a;Aside 在Vue项目中&#xff0c;侧边栏&#xff08;Aside&#xff09;是一个常见的组件&#xff0c;用于展示导航菜单。本文将详细介绍如何创建一个侧边栏组件&#xff0c;包括如何引入el-menu组件、定义路由、传递props以及编写MenuTree子…

LRU go cache的实现

目录 LRU算法LRU原理LRU实现Redis LRU算法实现1. 内存淘汰策略2. LRU算法的实现3. LRU vs LFURedis中的LRU使用场景 基于LRU的缓存库go-cache安装使用代码解析 hashicorp/golang-lru安装使用代码解析 groupcache安装使用代码解析缓存淘汰算法并发缓存组一致性哈希防止缓存击穿—…

LeetCode之双指针

125. 验证回文串 class Solution {public boolean isPalindrome(String s) {// 获取输入字符串 s 的长度int len s.length();// 创建一个 StringBuilder 对象 result 用于存储处理后的字符串StringBuilder result new StringBuilder();// 遍历输入字符串 sfor (int i 0; i …

[N1CTF 2018]eating_cms1

进入到页面是一个login登录页面 . 去访问他的register.php页面进入注册页面. 注册进入. 一眼文件包含. 去读取一下user.php http://2641f658-8af4-4626-92d0-ceb19180ea92.node5.buuoj.cn:81/user.php?pagephp://filter/convert.base64-encode/resourceuser 解码. <?p…

git中,隐藏application.properties文件,修改不用提交了

git中&#xff0c;隐藏application.properties文件&#xff0c;修改不用提交了 A、将文件名放入 .gitignore 文件中 B、执行git命令隐藏文件 执行在ide上执行命令 a、执行隐藏命令 git rm --cached src/main/resources/application.properties b、执行提交命令 git commit -m…

AI产品经理:2024年职场发展的新机遇

前言 这两年&#xff0c;AI 骤然“火”了起来&#xff0c;可谓出现了重大“转折”。就在这短短两年间&#xff0c;全球各大“大厂”几乎在同一时间争先恐后地跟进 AI 技术。从 ChatGPT 发布起&#xff0c;谷歌、Facebook、亚马逊等纷纷紧跟其后&#xff0c;国内的百度、腾讯、…

NLP从零开始------文本中阶处理之序列到序列模型(完整版)

1. 序列到序列模型简介 序列到序列( sequence to sequence, seq2seq) 是指输入和输出各为一个序列(如一句话) 的任务。本节将输入序列称作源序列&#xff0c;输出序列称作目标序列。序列到序列有非常多的重要应用&#xff0c; 其中最有名的是机器翻译( machine translation), 机…

【EI会议末轮截稿通知】第三届电子信息技术国际学术会议(EIT 2024)

第三届电子信息技术国际学术会议&#xff08;EIT 2024&#xff09; The 3rd International Conference on Electronic Information Technology 重要信息 大会官网&#xff1a;www.ic-eit.net 三轮截稿时间&#xff1a;2024年9月16日23:59分&#xff08;后续不再征稿&#x…

鸿蒙(API 12 Beta6版)GPU加速引擎服务【自适应VRS】

XEngine Kit提供自适应VRS功能&#xff0c;其通过合理分配画面的计算资源&#xff0c;视觉无损降低渲染频次&#xff0c;使不同的渲染图像使用不同的渲染速率&#xff0c;能够有效提高渲染性能。 接口说明 以下接口为自适应VRS设置接口&#xff0c;如要使用更丰富的设置和查询…

Unreal Fest 2024 虚幻引擎影视动画制作的普遍问题

———————————————————————————————————————— 本文为Unreal Fest Shanghai2024讲座内容笔记&#xff0c;非本人所著&#xff0c;原演讲人李文磊。 ————————————————————————————————————————…

Luigi:一个强大的Python模块,构建复杂的批处理作业管道的高效工具

在现代数据处理的大潮中&#xff0c;构建和管理复杂的数据管道是极其重要的一环。Luigi&#xff0c;作为一个强大的Python模块&#xff0c;为用户提供了构建复杂的批处理作业管道的高效工具。它不仅能够处理依赖关系、工作流管理、可视化等功能&#xff0c;还内置对Hadoop的支持…

c/c++面试100道

1.一道笔试题解析_哔哩哔哩_bilibili P20&#xff1a;#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER) 1、 offsetof 宏是 C 语言中用于计算结构体成员相对于结构体起始地址的偏移量的宏定义。这个宏的定义如下&#xff1a; #define offsetof(TYPE, …

树形结构-数据结构

一、基本知识 树&#xff1a;一对多的树形结构顶层的结点&#xff1a;称为根节点叶子结点&#xff08;终端结点&#xff09;&#xff1a;最外围的结点&#xff0c;只有前驱结点&#xff0c;没有后继结点的结点&#xff0c;其结点的度是0分支结点&#xff1a;分支点是描述数据结…

Dubbo 与 Zookeeper 在项目中的应用:原理与实现详解

引言 在微服务架构日益普及的今天&#xff0c;如何实现服务的高效调用和管理成为了关键问题。Dubbo 作为阿里巴巴开源的高性能 RPC 框架&#xff0c;在分布式服务治理方面具有显著的优势。Zookeeper 作为一款分布式协调服务&#xff0c;能够高效地管理和协调服务节点信息。因此…