【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)的过程中衍生品,最终形成体系,成为一…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...










