【Spring 】执行流程解析:了解Bean的作用域及生命周期

 哈喽,哈喽,大家好~ 我是你们的老朋友:保护小周ღ  


今天给大家带来的是 Spring 项目的执行流程解析 Bean 对象的6 种作用域以及生命周期本文将为大家讲解,一起来看看叭~


本期收录于博主的专栏:JavaEE_保护小周ღ的博客-CSDN博客

适用于编程初学者,感兴趣的朋友们可以订阅,查看其它 “JavaEE基础知识”。

更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* ‘


一、Spring 的执行流程 

Bean 执行流程(Spring 执行流程):启动 Spring 容器 -> 读取Spring 配置文件-> 实例化 Bean 对象(分配内存空间,从无到有) -> Bean 注册到 Spring 中(存操作) -> 将 Bean 注入到需要的类中(取操作)。

 Spring 注解相关操作感兴趣得老铁可以阅读博主得另一篇博客:

【Spring】使用注解读取和存储Bean对象_保护小周ღ的博客-CSDN博客


二、Bean 的作用域

Spring 是一个包含众多工具方法的 IoC 容器,也可以认为 Spring 就是用来读取和存储 Bean 对象的,那么 Bean 对象就是Spring 中一个至关重要的角色。

2.1 通过案例来观察 Spring 中Bean 对象默认的作用域

设计一个公共的 Student 类的Bean对象,注册到 Spring 容器中,提供给  A用户 和 B用户使用,A用户不讲武德悄悄地修改 Student 类型Bean 对象的数据,B 用户在使用的 Bean 对象的时候发现数据已经被篡改了,相当的恼火~

Student 类如下:

@Data
public class Student {private int id; // 学号private String name; // 姓名private int age; // 年龄private String sex; // 性别
}

给大家介绍一个第三方的框架: lombok 

"Lombok"是一个在Java开发中非常常用的开源框架。它的目标是通过自动化生成Java代码的样板代码来简化开发过程,减少冗余代码,并提高代码的可读性。

Lombok提供了一系列的注解,例如@Data、@Getter、@Setter、@NoArgsConstructor等,通过在类上添加这些注解,可以自动生成对应的getter、setter、构造函数等方法。这样可以大大简化Java类的编写,提高开发效率

要使用Lombok,您需要在项目中添加Lombok的依赖,并在IDE中安装Lombok插件,以便在编译和运行时正确处理Lombok的注解。

 Lombox 依赖:

 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version><scope>provided</scope></dependency>

博主使用 @Data 注解就来源于 lombox ,@Data包含了 @Setter 和 @Getter  注解,也就是自动给Student 类创建 set 和 get 方法。


公共的Bean 对象,注入到 Spring 中:

@Component
public class Users {//使用方法注解将 学生张三注入到 Spring 中@Beanpublic Student getStu() {Student stu = new Student();stu.setId(123456);stu.setName("张三");stu.setAge(18);stu.setSex("男");return stu;}
}

用户A 从Spring 中获取 stu Bean 对象,并进行修改:

@Controller
public class UserA {//从Spring 中获取Bean 对象@Resource //@Autowiredprivate Student stu;public Student getStu() {System.out.println("用户A获取原Bean对象"+ '\n'+ stu.toString());//对原Bean 的数据进行修改stu.setName("李四");stu.setSex("女");return stu;}
}

用户B 从Spring 中获取 stu Bean 对象,进行使用(打印):

@Controller
public class UserB {//从Spring 中获取Bean 对象@Resource //@Autowiredprivate Student stu;public Student getStu() {System.out.println("用户B获取被用户A修改过的 Bean :" + '\n' + stu.toString());return stu;}
}

启动类中获取用户A 和 用户B 对象,调用getStu() 方法,获取 stu Bean对象:

public class App {public static void main(String[] args) {//1. 获取Spring 上下文对象,里面管理着 bean 对象ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");//2. 获取指定的 Bean 对象UserA userA = context.getBean("userA", UserA.class);Student stuA = userA.getStu();System.out.println("用户A:" + stuA.toString());UserB userB = context.getBean("userB", UserB.class);Student stuB = userB.getStu();System.out.println("用户B:"+ stuB.toString());}
}


案例分析:

以上操作的的执行结果的原因 Bean 默认情况下是单例模式(singleton:一个类只有一个实例),也就是说用户 A 和 用户 B 操作的都是同一个Bean 对象,所以用户A 修改了唯一的 Bean , 用户B 获取到的 Bean 就是被修改后的了。

在Spring 中Bean 的作用域默认是singleton 单例模式~


2.2 Bean 对象的 6 种作用域

限定程序中变量的可用范围叫做作用域,Bean 对象的作用域指的是在 Spring 整个生命周期中的某种行为模式,例如:单例作用域(singleton)的意思就是在整个 Spring 中只有一份实例,且全局共享,当其他人修改了这个唯一的一份实例后,另一个人再获取到的实例,就是被修改后的值了。

Spring框架为Bean对象提供了多种作用域选项。以下是Spring框架中常见的6种Bean对象作用域:

  1. Singleton(单例):在整个应用程序中只存在一个Bean实例。每次请求都将返回相同的实例。获取Bean(通过applicationContext.getBean等方法获取),装配Bean(即通过@Autowired,@Resource)

  2. Prototype(原型):每次请求将创建一个新的Bean实例。每次请求都返回不同的实例。获取Bean(通过applicationContext.getBean等方法获取),装配Bean(即通过@Autowired,@Resource)

  3. Request(请求):在每次HTTP请求中,都会创建一个新的Bean实例。每个HTTP请求都返回不同的实例。

  4. Session(会话:在用户会话期间,都会创建一个新的Bean实例。对于同一用户的后续请求,将返回相同的实例。

  5. Global Session全局会话:在整个应用程序的全局会话期间,都会创建一个新的Bean实例。对于同一全局会话的后续请求,将返回相同的实例。

  6. Application应用程序:在整个Web应用程序的生命周期内,都会创建一个新的Bean实例。每个Web应用程序都返回相同的实例。

注意:作用域的使用取决于具体的应用场景和需求。Spring框架还支持自定义作用域,普通的Spring 项目只支持 singleton (单例),prototype (多例),剩下的4种状态是在 SpringMVC项目中可以设置。


2.3 给Bean 对象设置作用域

使用 @Scope 标签就可以用来声明 Bean 的作用域, 如以下代码所示:

@Component
public class Users {//声明为多例模式,每此请求都会实例一个新的Bean对象@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) //使用方法注解将 学生张三注入到 Spring 中@Bean(name = "stu") //给 Bean 对象起一个名字public Student getStu() {Student stu = new Student();stu.setId(123456);stu.setName("张三");stu.setAge(18);stu.setSex("男");return stu;}
}

@Scope 标签既可以修饰方法也可以修饰类,此处是修饰方法,@Scope 有两种设置方式:

1. 直接设置值: @Scope("prototype")

英语好的朋友可以直接把单词记住,也是蛮直接方便的昂~

2.使用枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

此时我们给上述例子Student 类型的Bean 对象设置了多例模式,这个时候运行一下看看:


三、Bean 的生命周期

所谓 Bean(对象) 生命周期指的就是一个普通对象从创建到销毁的整个过程,我们把整个过程称之为对象的生命周期。Bean 对象也就是一个普通的实例对象。

Bean 对象的生命周期分为以下五个部分:

1. 实例化: Bean (为 Bean对象分配内存空间(堆区))

2. 设置属性:在实例化后,容器会将配置的属性值或引用注入到Bean对象中,可以通过构造函数、setter方法或字段注入的方式完成。

3. Bean 对象的初始化 :Bean对象的初始化流程通常包括以下几个步骤:

  • 加载Bean定义:首先,容器会读取配置文件或通过注解扫描等方式,获取Bean的定义信息,并将其存储在内存中。

  • 创建Bean实例:根据Bean的定义信息,容器会实例化Bean对象。这可以通过调用默认构造函数或使用工厂方法等方式来完成。

  • 注入依赖:一旦Bean实例创建完成,容器会检查Bean定义中所声明的依赖关系,并将相应的依赖注入到Bean实例中。依赖注入可以通过构造函数、setter方法或字段注入方式来实现。

  • 实现Aware接口:如果Bean实现了特定的Aware接口(如BeanNameAware、BeanFactoryAware等),容器会调用相应的回调方法,以便提供一些额外的关于容器的信息。

  • Bean初始化前的处理:在Bean实例初始化之前,容器会调用BeanPostProcessor接口的实现类的postProcessBeforeInitialization()方法,允许开发者在初始化之前进行一些自定义逻辑的处理。

  • 初始化Bean:实例化过程完成后,容器会根据Bean定义中的配置调用初始化方法。这可以是通过在Bean类中标注@PostConstruct注解或实现InitializingBean接口的afterPropertiesSet()方法来完成。

  • Bean初始化后的处理:在Bean实例初始化之后,容器会再次调用BeanPostProcessor接口的实现类的postProcessAfterInitialization()方法,允许开发者在初始化之后进行一些自定义逻辑的处理。

  • 完成Bean的初始化:至此,Bean的初始化流程完成,可以将其添加到容器中,供其他Bean进行依赖注入或其他操作使用。

需要注意的是,以上是一个典型的Bean对象初始化流程,实际应用中可能会有一些差异,例如,使用了代理、继承了父类等情况会导致初始化流程有所不同。同时,不同的容器实现也可能会有一些细微的差异。

4. 使用 Bean : Bean 对象,就是一个普通的实例化的对象,使用都是一样的,看咋类是咋设计的

5. 销毁 Bean :

销毁Bean对象可以通过以下几种方式实现:

  • 使用Destroy方法:可以在Bean类中实现DisposableBean接口,并重写其中的destroy()方法。在容器销毁Bean实例时,会自动调用该方法来销毁Bean对象。
public class MyBean implements DisposableBean {// ...@Overridepublic void destroy() {// 销毁操作// ...}
}

  • 使用@PreDestroy注解:可以在Bean类的销毁方法上添加@PreDestroy注解,当容器销毁Bean实例时,会触发该注解标记的方法进行销毁操作。
public class MyBean {// ...@PreDestroypublic void destroy() {// 销毁操作// ...}
}

  • 配置销毁方法:在配置文件(如XML配置文件)中,可以通过指定destroy-method属性来指定Bean销毁时调用的方法。该方法可以是Bean类中的任意公开方法。
<bean id="myBean" class="com.example.MyBean" destroy-method="destroy"><!-- ... -->
</bean>

需要注意的是,销毁Bean对象的时机由容器管理,通常发生在容器关闭时。如果是单例Bean,则在容器关闭或手动调用销毁方法时触发销毁操作。如果是原型或会话作用域(session scoped)的Bean,则需要手动销毁。


执行流程图 :


实例化和初始化的区别:

实例化和属性设置时 Java 级别的系统 “事件”,操作过程不可以人为干预,而初始化是给开发者提供的,可以在实例化之后,类加载完成之前进行自定义 “事件” 处理。

总的来说,实例化是创建Bean实例的过程,而初始化是对已创建的Bean对象进行属性赋值和回调方法调用的过程。实例化是创建Bean对象的基础步骤,而初始化则是在实例创建完成后对Bean对象进行配置和准备的重要步骤。


举个例子形象的描述Bean 对象的生命周期:买房子

1. 实例化:在某市盖了一套毛坯房(从无到有,将字节码转换为内存中的对象,只是分配了内存)

2. 设置属性:(容器会将配置的属性值或引用注入到Bean对象中)。购买装修材料,引入外部资源。

3. 初始化:给房子装修~

  • 各种通知:联系各种装修师傅,水工,电工,瓦工……
  • 初始化的前置工作:装修师傅现场考察毛坯房的环境,制定装修方案。
  • 进行初始化工作:(@PostConstruct 初始化、init-method 初始化),装修师傅进行装修,其中有装修技术好的,有装修技术差的。
  • 初始化的后置工作: 装修完毕之后对房子进行清理。

4. 使用 Bean 对象: 拎包入住~

5. 销毁 Bean 对象: 拆,或者卖掉这套房子~

一定是先设置属性,再进行初始化操作。


好了,到这里,【Spring 】执行流程解析:了解Bean的作用域及生命周期 博主已经分享完了,希望对大家有所帮助,如有不妥之处欢迎批评指正。 

下期预告:【SpringBoot】框架~

感谢每一位观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* 

遇见你,所有的星星都落在我的头上……

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

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

相关文章

latex3【排版】

多行公式排版&#xff1a;&#xff08;gather、align、split、cases&#xff09; \section{多行公式}%gather环境\begin{gather} abba \\ abcbaccbacab\end{gather}\begin{gather*} abba \\ abcbaccbacab\end{gather*}​\begin{gather} abba \\ 123 \notag …

【NLP】多头注意力概念(02)

接上文: 【NLP】多头注意力概念(01) 五、计算注意力 将 Q、K 和 V 拆分为它们的头部后,现在可以计算 Q 和 K 的缩放点积。上面的等式表明,第一步是执行张量乘法。但是,必须先转置 K。 展望未来,每个张量的seq_length形状将通过其各自的张量来识别,以确保清晰…

学习记录——SpectFormer、DilateFormer、ShadowFormer、MISSFormer

SpectFormer: Frequency and Attention is what you need in a Vision Transformer, arXiv2023 频域混合注意力SpectFormer 2023 论文&#xff1a;https://arxiv.org/abs/2304.06446 代码&#xff1a;https://badripatro.github.io/SpectFormers/ 摘要视觉变压器已经成功地应用…

网络套接字编程(三)(HTTP)

gitee仓库&#xff1a;https://gitee.com/WangZihao64/linux/tree/master/CalTcp 一、重谈协议 协议是一种“约定”&#xff0c;这种约定是双方都知道的。有了一致的约定&#xff0c;双方才能够正常地进行通信。协议在网络的第一篇博客中也提到过&#xff0c;协议是双方进行通…

python opencv 级联Haar多目标检测

一、基于OpenCV的haar分类器实现笑脸检测 1、Haar分类器介绍 &#x1f680;Haar分类器是一种基于机器学习的目标检测算法&#xff0c;它使用Haar特征描述图像中的目标。Haar特征是基于图像亮度的局部差异计算得出的&#xff0c;可以用来描述目标的边缘、角落和线条等特征。 使用…

基于PyQt5的UI界面开发——信号与槽

信号与槽的机制 PyQt5采用了一种被称为“信号与槽”机制的编程模式&#xff0c;用于处理对象间的通信和事件处理。在PyQt5中&#xff0c;信号&#xff08;signal&#xff09;是对象发出的特定事件&#xff0c;例如按钮被点击、文本被修改等。而槽&#xff08;slot&#xff09;…

用Maven的exec插件执行Java程序

Maven的exec插件介绍 利用maven的exec插件可以执行系统和Java程序。 官网资源 exec插件官网&#xff1a;https://www.mojohaus.org/exec-maven-plugin/java-mojo.html Goals exec:exec表示在一个单独的进程内执行系统和Java程序。 exec:java表示在当前的Java虚拟机内执行J…

Docker高级——网络配置

Docker网络 默认网络 安装 Docker 以后&#xff0c;会默认创建三种网络&#xff0c;可以通过 docker network ls 查看 [roottest ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 6f24f7cbfa10 bridge bridge local 2dc34a1c0f04 host host…

MobPush Android For Unity

本文档以unity2020.3.41演示 集成准备 注册账号 使用MobSDK之前&#xff0c;需要先在MobTech官网注册开发者账号&#xff0c;并获取MobTech提供的AppKey和AppSecret&#xff0c;详情可以点击查看注册流程 下载.unitypackage包 打开 Github 下载 MobPush-For-Unity 项目&am…

C++模拟实现vector

目录 1.代码实现 2.注意事项 1.成员变量 2. 不能使用memcpy函数拷贝数据 1.用string类型测试时&#xff0c;要考虑到vs可能把数据存储在数组buffer里面 3.insert函数中指针的失效性 1.加引用&#xff0c;那么就不能传常量&#xff0c;比如v.begin() 3 2.加引用&#x…

【ArcGIS Pro微课1000例】0028:绘制酒店分布热力图(POI数据)

本文讲解在ArcGIS Pro中文版中,基于长沙市酒店宾馆分布矢量点数据(POI数据)绘制酒店分布热力图。 文章目录 一、加载酒店分布数据二、绘制热度图参考阅读: 【GeoDa实用技巧100例】004:绘制长沙市宾馆热度图 【ArcGIS微课1000例】0070:制作宾馆酒店分布热度热力图 一、加载…

【机器学习】基于卷积神经网络 CNN 的猫狗分类问题

文章目录 一、卷积神经网络的介绍1.1 什么是卷积神经网络1.2 重要层的说明1.3 应用领域二、 软件、环境配置2.1 安装Anaconda2.2 环境准备 三、猫狗分类示例3.1 图像数据预处理3.2 基准模型3.3 数据增强3.4 dropout层四、总结 一、卷积神经网络的介绍 1.1 什么是卷积神经网络 …

el-table找出当前单元格与对应的上下列的值

当前单元格与对应的上下列的值如果不相同就设置个红色边框 当前单元格与对应的上下列的值如果不相同就设置个红色边框 当前单元格与对应的上下列的值如果不相同就设置个红色边框 以下是示例代码&#xff0c;对tableData数据的name字段进行处理 如果当前name值与上一条数据的na…

mybatis作用域和生命周期解读

目录 SqlSessionFactoryBuilder SqlSessionFactory SqlSession 依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器&#xff0c;并将它们直接注入到你的 bean 中&#xff0c;因此可以直接忽略它们的生命周期。 SqlSessionFactoryBuilder 这个类可以被实例化…

EfficientNet论文笔记

EfficientNet论文笔记 通过NAS平衡了channel&#xff0c;depth&#xff0c;resolution&#xff0c;发现在相同的FLOPs下&#xff0c;同时增加 depth和 resolution的效果最好。 数据集效果小于resolution怎么办&#xff1f; EfficientNet—b0框架 表格中每个MBConv后会跟一个…

科技资讯|Apple Vision Pro新专利,关于相对惯性测量系统的校正

美国专利商标局正式授予苹果一项 Apple Vision Pro 相关专利&#xff0c;该专利涵盖了具有视觉校正功能的相对惯性测量系统。这样的系统用于弥补头显内的眼前庭不匹配&#xff0c;当 VR 头显中发生的事情与现实世界环境中发生的运动不匹配时&#xff0c;可能会导致恶心。 苹果…

11. 利用Tomcat服务器配置HTTPS双向认定

文章目录 Tomcat配置HTTPS1.为服务器生成证书2.为客户端生成证书3.让服务器信任客户端证书4.将该文件导入到服务器的证书库&#xff0c;添加为一个信任证书使用命令如下&#xff1a;5.查看证书库6.让客户端信任服务器证书7.配置tomcat8.验证 Tomcat配置HTTPS 1.启动cmd控制台&…

DirectX12(D3D12)基础教程(二十二) ——HDR IBL 等距柱面环境光源加载和解算及 GS 一次性渲染到 CubeMap

前序文章目录 DirectX12&#xff08;D3D12&#xff09;基础教程&#xff08;一&#xff09;——基础教程 DirectX12&#xff08;D3D12&#xff09;基础教程&#xff08;二&#xff09;——理解根签名、初识显存管理和加载纹理、理解资源屏障 DirectX12&#xff08;D3D12&…

【Linux】进程信号之信号的产生

进程信号 一 一、信号入门1、信号的一些特性2、信号的处理方式信号捕捉初识 3、Linux下的信号 二、信号的产生1、通过终端按键产生信号2、调用系统函数向进程发信号a、kill函数b、raise函数c、abort函数 3. 由软件条件产生信号4、硬件异常产生信号 结语 一、信号入门 什么是信号…

怎么解决亚马逊跟卖?为何卖家总是举报不成功?

以前大家都是从跟卖的时代走向现在的品牌化运营之路&#xff0c;但是现在跟卖已经从大家都模仿的对象变成了大部分卖家厌恶的对象&#xff0c;那么怎么解决这个跟卖问题呢&#xff1f;目前最直接的方法就是进入亚马逊后台进行举报&#xff0c;但是大概率是失败的。 一、举报违…