【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
【JavaEE】Spring的开发要点总结(4)
文章目录
- 【JavaEE】Spring的开发要点总结(4)
- 1. Bean的作用域
- 1.1 一个例子感受作用域的存在
- 1.2 通过例子说明作用域的定义
- 1.3 六种不同的作用域
- 1.3.1 singleton单例模式(默认作用域)
- 1.3.2 prototype原型模式
- 1.3.3 request请求作用域
- 1.3.4 session会话作用域
- 1.3.5 application全局/应用作用域
- 1.3.6 "websocket" HTTP WebSocket作用域
- 1.4 设置Bean的作用域
- 2. Bean的生命周期
- 2.1 Spring的执行流程
- 2.2 Spring 的生命周期
- 2.3 Bean的生命周期
- 2.3.1 Bean初始化
- 2.3.2 Bean生命周期代码演示
- 2.3.3 为什么属性设置比Bean初始化早
【JavaEE】Spring的开发要点总结(4)
在学习Spring中,Bean是最核心的操作资源
- 使用学习Bean对象是一个重点,我们已经知道如何存储它,获取它,现在我们要知道:
- 它的作用域,我们才可以知道怎么使用,才能得心应手,符合预期~
- 它的生命周期,我们才能更加清楚的了解它的“生与死”,即程序执行的过程~
1. Bean的作用域
在学习C语言或者JavaSE的时候,熟悉一个变量的作用域非常重要,否则会出现很多错误,并且违背一些设计上的初心~
- C语言
- 全局变量,整个源文件可以访问,代码从上到下执行,局部优先,隔着源文件需要extern…
- 局部变量,在代码块中生效,在方法中生效,代码从上到下执行
- 静态变量,局部变量的作用域,全局变量的生命周期~
- Java
- 修饰访问限定符
- 局部变量…
- 成员变量,静态成员变量…
知己知彼,才能百战百胜~
1.1 一个例子感受作用域的存在
之前的代码,我们只是一个简单的读操作,没有涉及其他,所以作用域感受不明显,接下来一个例子说明一下~
背景故事:
一个公司开发了一个外卖平台,这个公司打算将这个平台卖给别的公司,赚收成和维护费,但是每个公司都有特定的要求,而员工三人(小马、大马、老马),负责这个项目,小马负责公司原本的代码,大马负责A公司的外卖平台的代码,老马则负责B公司。
大马和老马的工作就是,对一些功能进行删减,添加个别的功能~
三人各自完成各自的业务~
所以就会如下的项目结构(实际情况要比这复杂很多,这个例子只是为了演示罢了):
- 小马代表UserController
- 大马代表UserController1
- 老马代表UserController2
这个Users类,就是一些原始的User的诞生和定义的地方~
- 这个类是一个公共类
- 这不代表这个里面诞生的对象就是公共的,而是存储Bean对象的手段是公共的
那么可能就会有以下场景:
再每次设置后都打印一次:
System.out.println(user2);
他们原本的意思就是,他们从spring中获取一个Bean对象(用户),设置对应的属性,为自己所用~
现在我们来测试一下:
@Component
public class Test {@Autowiredprivate UserController userController;@Autowiredprivate UserController1 userController1;@Autowiredprivate UserController2 userController2;public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");Test test = context.getBean("test", Test.class);test.userController.doMethod();test.userController1.doMethod();test.userController2.doMethod();}
}
从结果可以看出,下一次的更新,是在前一次更新的基础上进行的!
- 而小马大马老马三个人的操作都没有问题,他们都不知道对方进行修改了 ~
所以可以说明,他们用的Bean,是同一个!就像C语言全局变量那样~
这就是作用域中的一种:单例Bean对象
- 这里的单例跟我们之前的单例不一样,之前的单例是那个类的实例只有一个
- 而这里的单例是,这个Bean对象的实例只有一个
- 也就是说这个类型的Bean对象,名字为这个名字的Bean对象,有且只有一个~
改变Bean对象的作用域也很简单,只需要一个注解@Scope(意思就是作用域)~
默认情况下就是:singleton
我们如果要让小马大马老马获得的Bean对象都不一样,可以设置为:
prototype(原型/多例)
- 原型 => 每次获取该 Bean对象,都是重新获取初始的那一个
- 多例 => 这个类型这个名字的 Bean对象,有多个存在!
- 从结果可以看出,作用域的改变!
1.2 通过例子说明作用域的定义
Bean的作用域指的就是Bean对象在Spring整个框架中的某种行为模式:
- 比如singleton,单例模式,就表示这个Bean对象在整个Spring容器中只有一份,它是全局共享的,那么当其他人修改这个值之后,另一个人读取到的就是修改后的值
- 再比如prototype,原型模式,就表示这个Bean对象在整个Spring中可以存在多份,并且每次DI的时候,都是崭新的一个Bean对象,不同人获得的Bean是不一样的
- 所以prototype模式下的Bean对象的作用域就是:需要注入这个Bean的那个类的一个实例内部
- 类比两个不同的方法中定义的同一类型同一名字的变量~
1.3 六种不同的作用域
- singleton:单例作用域
- prototype:原型作用域
- request:请求作用域
- session:会话作用域
- application:全局作用域
- websocket:HTTP WebSocket作用域
Spring普通项目( Spring Core)其实就前面两种:singleton 和 prototype
后四种值则是在 Spring MVC 项目中的值
1.3.1 singleton单例模式(默认作用域)
单例模式的效率比较高(性能好)
- 只有第一次去加载它
经典的面试题:单例模式的Bean是线程安全的吗?
不是线程安全的~
- 所有人共同操作的变量,一定不是线程安全的
解决方案:使用ThreadLocal(本地线程变量)
- 这是解决线程安全的其中一种方式!
文章推荐:ThreadLocal不好用?那是你没用对!| Java Debug 笔记 - 掘金 (juejin.cn)
ThreadLocal的基础方法:
- set方法
- get方法
- remove方法
可能存太多没有remove,内存溢出的问题也会出现,感兴趣的可以去了解一下
相比于使用锁来解决线程安全问题
- 使用ThreadLocal可能会导致结果与锁不一致的情况
- 特别是在多个线程之间存在依赖关系的情况下。
- 因为每个线程都有自己的数据副本,如果线程之间需要共享数据并进行协作,那么就需要额外的协调机制来保证数据的一致性。
- 否则,可能会出现一个线程修改了数据,但其他线程并不知道的情况,导致结果不一致。
所以在使用ThreadLocal解决线程安全问题时,**需要根据具体的业务场景来评估是否适合使用ThreadLocal,**并确保线程之间的数据协作和一致性。
对于一些依赖全局状态的场景,使用锁可能更适合。
1.3.2 prototype原型模式
每次获取(DI)的都是一个原型的对象:
1.3.3 request请求作用域
顾名思义,在每一次HTTP请求的时候,创建一次原型,与prototype类似
在一次HTTP请求和响应中,共享Bean
注意:限定在Spring MVC中使用
因为Spring Core项目不支持HTTP
Spring MVC项目也叫作 Spring Web项目,支持HTTP
1.3.4 session会话作用域
顾名思义,一个HTTP Session中,共享Bean
- 例如记录一个用户的登录信息,同一个session,每次获取Bean的时候不要原型
注意:限定在Spring MVC中使用
后面四种可能会比较难理解,这是因为我们还没有接触Spring MVC,所以不太了解具体用法!
- 之后的实践肯定会对这些知识更加清晰!
1.3.5 application全局/应用作用域
在一个http servlet Context中,共享Bean
即一个Context容器,共享Bean
- web应用的上下文信息,例如记录一个应用的共享信息
注意:限定在Spring MVC中使用
对于普通的Spring项目是不能用这个值的
但是对于singleton单例模式,Bean的作用域不超过一个ApplicationContext对象(一个context是一个容器,不同context进行各自的注入…):
singleton和application有什么区别呢?
- 前者是Spring Core的全局作用域,作用于IoC容器
- 后者是Spring MVC(Spring Web)的全局作用域,作用于Servlet容器
了解即可
1.3.6 “websocket” HTTP WebSocket作用域
在一个HTTP WebSocket的生命周期中,共享Bean
就是一个特殊项目里使用的特殊值罢了
注意:限定在Spring WebSocket中使用
WebSocket的每次会话中,保存了一个Map结构的头信息,将用来包裹客户端消息头。第一次初始化后,直到WebSocket结束都是同一个Bean。
如果对WebSocket项目感兴趣的同学可以去学习,如果不感兴趣,了解一下也可以
1.4 设置Bean的作用域
- 直接设置
- @scope(“prototype”)
- 利用全局变量
- 不用记忆单词,借助题词
- 不用记忆单词,借助题词
效果一致~
对于 & :了解即可!
2. Bean的生命周期
2.1 Spring的执行流程
笼统的流程:
- 回答问题的时候,不用讲太细致~
- 启动容器
-
加载配置文件(根据参数)
-
完成Bean的实例化(根据提供的扫描路径,找五大类注解)
- 这样Bean对象就成型了,但是是游离在内存中
- 这样Bean对象就成型了,但是是游离在内存中
-
注册Bean对象到容器中
- 装配Bean的属性(DI)
6.……
2.2 Spring 的生命周期
跟流程基本一致(粗糙的了解):
- 启动容器
- 读取配置进行Bean实例化
- 将Bean加入到容器中
- 装配Bean属性(给当前类的属性进行赋值,DI)
- 运行业务代码
- 销毁Bean
- 关闭容器
2.3 Bean的生命周期
所谓的生命周期指的是一个对象从诞生到销毁的整个生命周期,我们把这个过程叫做一个对象的生命周期
Spring的一生其实也差不多是Bean 的一生吧~
Bean的生命周期,也是经典的面试题!
- 这一部分讲的就比较细致,但是也是了解为主~
Bean的生命周期分为以下5大部分:
- 实例化Bean
- 只是分配内存空间,现在Bean既没有初始化,而且还是游离在内存中的
- 设置属性
- 进行依赖注入,将需要的但没有初始化的Bean对象注入到属性中,Bean不游离了
- Bean初始化
- 流程较多,大概就是对Bean进行一系列的操作,然后Bean里面的值是有意义的
- 其中就可能涉及Bean注入的属性
- 使用Bean
- 销毁Bean
2.3.1 Bean初始化
- 进行各种通知:如BeanNameAware、BeanFactoryAware…的接口方法
- 就是暴露一个判断而已,就是告知你Bean的名字设置好了…
- 至于你知道了这个通知后,进行什么逻辑就看你了~
- 而系统也会自动去干一些事情~
- 初始化前置方法(前戏,准备)
- 执行初始化方法(设置就一定会执行,不设置就不会执行)
- 注解的方式:@PostConstruct
- xml的方式:init-method方法
- 初始化后置方法
- 进行一些额外的操作和设置,以确保Bean在使用之前处于正确的状态
- xml的方式:destroy-method的值
- 注解的方式:@PreDestroy
2.3.2 Bean生命周期代码演示
- 以这个实行了BeanNameAware接口的类为例
如图是注解的方式去定义初始化方法
如图是xml的方式去决定使用什么初始化方法
- init-method的值对应的就是方法名,并且必须存在!
用注解设置多个初始化方法也更加方便~
- 这是用注解的方式设置销毁Bean的方法
- 这是用xml的方式设置销毁Bean的方法
对于初始化和销毁方法的设置,还有很多其他的方法!
- 但是注解就是香!
- xml的方式一次就一个
测试:
用子类,有更多的方法
获取Bean,使用Bean
扫描路径不要删掉,即使没用也要设置的
效果:
注解的优先级比较高~
顺序正如我们所料~
2.3.3 为什么属性设置比Bean初始化早
其实这个很容易想,例如一下操作:
如果user这个没有指向一块内存空间,只是null,那么就会空指针异常~
而实例化和属性注入之后,相当于在这里放了个箱子,之后的操作有了对象
文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆!Spring Core普通项目的讲解告一段落,接下来是Spring Boot的学习,敬请期待!
代码位置:SpringDemo4/src/main/java · 游离态/马拉圈2023年8月 - 码云 - 开源中国 (gitee.com)
相关文章:

【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
【JavaEE】Spring的开发要点总结(4) 文章目录 【JavaEE】Spring的开发要点总结(4)1. Bean的作用域1.1 一个例子感受作用域的存在1.2 通过例子说明作用域的定义1.3 六种不同的作用域1.3.1 singleton单例模式(默认作用域…...
P1320 压缩技术(续集版)
题目描述 设某汉字由 N N N \times N NN 的 0 \texttt 0 0 和 1 \texttt 1 1 的点阵图案组成。 我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有…...

k8s(七) 叩丁狼 service Ingress
负责东西流量(同层级/内部服务网络通信)的通信 service的定义 apiVersion: v1 kind: Service metadata:name: nginx-svclabels:app: nginx-svc spec:ports:- name: http # service 端口配置的名称protocol: TCP # 端口绑定的协议,支持 TCP、…...

Android Studio 关于BottomNavigationView 无法预览视图我的解决办法
一、前言:最近在尝试一步一步开发一个自己的软件,刚开始遇到的问题就是当我们引用 com.google.android.material.bottomnavigation.BottomNavigationView出现了无法预览视图的现象,我也在网上查了很多中解决方法,最后在执行了如下…...

【STM32】小电流FOC驱控一体板(开源)
FOC驱控一体板 主控芯片stm32f103c8t6 驱动芯片drv8313 三相电流采样 根据B站一个UP主的改的(【【自制】年轻人的第一块FOC驱动器】),大多数元器件是0805,实验室具备且便于自己动手焊接 。 晶振用的是无源晶振,体…...

代码分析:循环创建N个子进程——为什么最后一个属于父进程?
黑马C/C 2018年32期代码分析 //循环创建n个子进程 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h>int main() {int i 0;for(i0; i<3; i){//创建子进程pid_t pid fork();if(pid&…...
【SpringBoot面试题整理-超级有效】
文章目录 1.SpringBoot如何解决跨域问题?2.为什么要用Spring Boot?3. Spring Boot的约定优于配置,你的理解是什么?4. SpringBoot有哪些优点?5. Spring Boot中自动装配机制的原理?6.SpringBoot支持哪些日志框…...

岩土工程仪器多通道振弦传感器信号转换器应用于隧道安全监测
岩土工程仪器多通道振弦传感器信号转换器应用于隧道安全监测 多通道振弦传感器信号转换器VTI104_DIN 是轨道安装式振弦传感器信号转换器,可将振弦、温度传感器信号转换为 RS485 数字信号和模拟信号输出,方便的接入已有监测系统。 传感器状态 专用指示灯方…...

西瓜书读书笔记整理(五)—— 第四章 决策树
第四章 决策树 4.1 基本流程4.1.1 什么是决策树算法4.1.2 决策树学习的目的4.1.3 决策树学习基本过程4.1.4 决策树学习基本算法4.1.5 递归结束的三种情况 4.2 划分选择4.2.1 信息增益(information gain)—— ID3 决策树学习算法属性划分准则4.2.2 信息增…...

STM32 4G学习
硬件连接 ATK-IDM750C模块可直接与正点原子 MiniSTM32F103开发板板载的ATK模块接口(ATK-MODULE)进行连接。 功能说明 ATK-IDM750C是正点原子(ALIENTEK)团队开发的一款高性能4G Cat1 DTU产品,支持移动4G、联通4G和…...
Golang 中实现实时聊天通讯
客户端代码 package mainimport ("fmt""log""net/url""os""os/signal""time""github.com/gorilla/websocket" )func main() {interrupt : make(chan os.Signal, 1)signal.Notify(interrupt, os.Interr…...
前端面试的性能优化部分(5)每天10个小知识点
目录 系列文章目录前端面试的性能优化部分(1)每天10个小知识点前端面试的性能优化部分(2)每天10个小知识点前端面试的性能优化部分(3)每天10个小知识点前端面试的性能优化部分(4)每天…...

【链表OJ 1】移除链表元素val
大家好,欢迎来到我的博客,此题是关于链表oj的第一题,此后还会陆续更新博客,如有错误,欢迎大家指正。 来源:https://leetcode.cn/problems/remove-linked-list-elements/description/ 题目: 方法一:定义prev和cur指针…...

复原 IP 地址——力扣93
文章目录 题目描述回溯题目描述 回溯 class Solution{public:static constexpr int seg_count=4<...

OSPF综合实验
实验题目如下: 实验拓扑如下: 实验要求如下: 【1】R4为ISP,其上只能配置IP地址: R4与其他所有直连设备间使用公有 【2】R3---R5/6/7为MGRE环境,R3为中心站点 【3】整个OSPF环境IP地址为172.16.0.0/16 【4】所有设备…...

安卓4G核心板开发板_MTK6785/MT6785(Helio G95)安卓手机主板方案
联发科MTK6785(Helio G95)安卓核心板采用八核 CPU 具有两个强大的 Arm Cortex-A76 处理器内核,主频高达 2.05GHz,外加六个 Cortex-A55 高效处理器。其强大的图形性能由 Arm Mali-G76 MC4 提供,速度可提升至 900MHz 。 …...

Linux 匿名页的生命周期
目录 匿名页的生成 匿名页生成时的状态 do_anonymous_page缺页中断源码 从匿名页加入Inactive lru引出 一个非常重要内核patch 匿名页何时回收 本文以Linux5.9源码讲述 匿名页的生成 用户空间malloc/mmap(非映射文件时)来分配内存,在内核空间发生…...

设计模式概述与UML图
文章目录 一、设计模式概述1. 软件设计模式的产生背景2. 软件设计模式的概念3. 学习设计模式的必要性4. 设计模式分类(1)创建型模式(2)结构型模式(3)行为型模式 二、UML图1. 类图概述2. 类图作用3. 类图表示…...

使用Vscode编辑keil工程
一、需要安装的插件 1. Keil Assistant 2. C/C 3. 中文配置: 二、插件配置 1. Keil Assistant 添加Keil的安装路径 接下来就可以使用vscode编辑Keil的工程了,调试编译和下载程序需要返回到Keil中进行操作。 三、Vscode常用快捷键 可以自定义进行配置…...

编译工具:CMake(一) | 简介与安装
编译工具:CMake(一) | 简介与安装 1. CMake简介1.1CMake的特点 2. CMake 安装 这个是CMake的图标 1. CMake简介 cmake 是 kitware 公司以及一些开源开发者在开发几个工具套件(VTK)的过程中衍生品,最终形成体系,成为一…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...