Spring中Bean的作用域问题

news2025/1/6 11:09:01

文章目录

  • 一、通过案例来简单体会一下Bean的作用域问题
  • 二、作用域定义
  • 三、Bean的作用域分类
      • singleton
      • prototype
      • request
      • session
      • application(了解)
      • singleton(单例作用域) 和 application (全局作用域)的区别
      • websocket(了解)
  • 四、Bean作用域设置
  • 总结


一、通过案例来简单体会一下Bean的作用域问题

User:


public class User {
    private String name;
    public User() {
        System.out.println("加载User");
    }
    public String sayHi() {
        return "Hello Dada!";
    }
}

🧡注意:
@DataLombok注解,作用大家可以自行了解一下,使用这个注解可以省去实体类中大量的get()set()toString()等方法。

公共Bean:


public class UserBean {
    
    public User user() {
        User user = new User();
        user.setName("哒哒");
        System.out.println("Bean原名:" + user.getName());
        return user;
    }
}

第一个用户使用公共Bean时,进行了修改操作:


public class ModifyUser {
    
    private User user1;

    public User getUser() {
        User user = user1;
        user.setName("阿巴阿巴");
        return user;
    }
}

第二个用户使用公共Bean时:


public class ReferUser {
    
    private User user1;
    public User getUser() {
        User user = user1;
        return user;
    }
}

打印第一个用户和第二个用户公共 Bean 的值:

public class Demo2 {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        ModifyUser modifyUser = context.getBean("modifyUser",ModifyUser.class);
        System.out.println("第一位用户修改user: " + modifyUser.getUser());

        ReferUser referUser = context.getBean("referUser",ReferUser.class);
        System.out.println("第二位用户就是看看user: " +referUser.getUser());
    }

结果:
在这里插入图片描述

可以看见,原来Username是"哒哒",现在是"阿巴阿巴",公共Bean的值发生了改变。

原因有两点:

  1. ModifyUsergetUser()表面创建了一个新的UserUser user = user1;)但只是把user指向了user1实际上修改的还是公共Bean
  2. Bean默认状态下是单例状态(singleton),也就是全局只有这一个Bean,所有人用的都是这一个对象,不再创建新的对象,因为使用单例可以很大程度上提高性能,所以在Spring中,Bean的作用域默认也是singleton单例模式。

在这里插入图片描述

二、作用域定义

这是我们之前对于作用域的理解:

限定程序中变量的可用范围叫做作用域,或者说在源码中定义变量的某个区域就叫做作用域。

Bean的作用域是指BeanSpring整个框架中的某种行为模式,比如singleton单例作用域,就表示Bean在整个Spirng中只有一份,它是全局共享的,如果别人修改了这个Bean,另外的人读到的就是被修改的Bean了。

那么Bean的作用域也不单单只有singleton单例作用域这一种。

三、Bean的作用域分类

singleton

  • 描述: singleton作用域下的BeanIoC容器中只存在一个实例: 获取Bean(使用applicationContext.getBean等方法获取)及装配Bean(使用@Autowired@Resource)都是同一个对象。
  • 场景: 通常是当所有人调用这个Bean都只是调用,而不是修改时,就使用singleton(通常是无状态的Bean使用该作用域。)
  • Spring默认使用该作用域

prototype

原型模式(多例模式)

通俗的理解就是本身是啥样就是啥样,比如上面的ModifyUser一开始和ReferUser都是拿到它原生的样子,本来等于“哒哒”的样子。

要保证每次都是原生的样子,那每次请求注入这个对象,都会new一个新对象,就是克隆(深克隆)一个原型的对象,所以我每次拿到的都是一个新的对象,要修改就是在这个新对象上进行修改,不会影响我的原型。

  • 描述: 每次对该作用域下的Bean请求都会创建新的实例:获取Bean(使用applicationContext.getBean等方法获取)及装配Bean(使用@Autowired@Resource)都是新的对象实例。
  • 场景: 当有人调用这个Bean会进行修改时,就使用prototype。(通常是有状态的Bean使用该作用域。)

request

请求作用域

  • 描述: 每次http请求都会创建新的Bean实例,类似于prototype
  • 场景: 一次http请求和响应共享一个Bean,来回的过程这个Bean共享
  • 限定在SpringMVC中使用,就是SpringWeb项目。

类似于Servlet,在Servlet上进行了封装。当使用ajax或使用浏览器时,访问一个地址,可以直接触发到程序里的某一个方法。

session

会话作用域

  • 描述: 在一个http session中,定义一个Bean实例
  • 场景: 用户会话的共享Bean,比如记录一个用户的登录信息
  • 限定SpringMVC中使用

比如我登陆了一个账号,那就是一次会话请求。
然后在整个操作期间,比如使用了30min,使用的都是一个账号,那么这个Bean在我的会话当中是一直共享的,此时另一个人登了另外账号,那么这个另外的账号和我的账号在逻辑上就是隔离的,不能相互共享的。每个会话都有自己的Bean
跟多线程中的ThreadLocal(每个线程都会有自己的变量)比较像。

application(了解)

全局作用域

  • 描述:在一个http servlet Context中,定义一个Bean实例
  • 场景:Web应用的上下文信息,比如,记录一个应用的共享信息
  • 备注:限定SpringMVC中使用

如:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

这一个ApplicationContext就是一个http servlet对象,如果此时我又新new了一个ApplicationContext,那么这两个对象信息就是不共享的,但一个ApplicationContext里面的信息是共享的。

singleton(单例作用域) 和 application (全局作用域)的区别

  1. 本身的应用范围是不一样的, singleton应用在Spring Core里面, application应用在SpringMVC里面
  2. singleton作用于IoC容器,而application作用于Servlet容器

websocket(了解)

socket通讯是应用层的协议,底层可以通过TCP通讯,也可以通过UDP通讯

  • 描述: 在一个HTTP WevSocket的声明周期中,定义一个Bean实例
  • 场景: WebSocket的每次会话中,保存了一个Map结构的头信息,将用来包裹客户端消息头。第一次初始化后,直到WebSocket结束都是同一个Bean
  • Spring WebSocket中使用

四、Bean作用域设置

设置成原型模式:

  1. 通过全局变量设置: @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  2. 直接通过值设置: @Scope("prototype")

在存Bean对象的时候,在Bean上加作用域。
在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述

你可以叫我哒哒呀
本篇到此结束
“莫愁千里路,自有到来风。”
我们顶峰相见!

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

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

相关文章

马尔科夫预测

一、模型介绍 天气有以下几种状态:晴天、雨天、阴天若已知天气当前处于某种状态,则天气未来的状态只与现在有关,与过去无关注意,天气的状态是随机的,只能求明天处于某一种状态的概率描述这种随机现象的模型&#xff0…

Visual Commonsense R-CNN 实现和代码

这篇文章比较早,但是对于因果介绍的比较详细,很值得学习。 代码:https://github.com/Wangt-CN/VC-R-CNN 代码花了挺长时间总算跑通了,在 3080 上调真是错误不断,后来换到 2080 又是一顿调才好。这里跑通的主要环境为 u…

代理模式详解

本文首更于《从零开始手把手教你实现一个简单的RPC框架》 。 1. 代理模式2. 静态代理3. 动态代理 3.1. JDK 动态代理机制 3.1.1. 介绍3.1.2. JDK 动态代理类使用步骤3.1.3. 代码示例 3.2. CGLIB 动态代理机制 3.2.1. 介绍3.2.2. CGLIB 动态代理类使用步骤3.2.3. 代码示例 3.3. …

win10系统安装Nginx

Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器,同时也提供了IMAP/POP3/SMTP服务。 Nginx可以进行反向代理、负载均衡、HTTP服务器(动静分离)、正向代理等操作。因为最近在公司使用到了Nginx 第一步:下载Nginx …

想找大数据工作需要学些什么

大数据开发做什么? 大数据开发分两类,编写Hadoop、Spark的应用程序和对大数据处理系统本身进行开发。大数据开发工程师主要负责公司大数据平台的开发和维护、相关工具平台的架构设计与产品开发、网络日志大数据分析、实时计算和流式计算以及数据可视化等…

12_FreeRTOS任务相关API函数

目录 FreeRTOS任务相关API函数介绍 获取任务优先级函数 设置任务优先级函数 获取任务数量函数 获取所有任务状态信息 获取指定的单个任务的状态信息 获取当前任务句柄 通过任务名获取任务句柄 获取任务栈历史最小剩余推栈 以表格的形式获取系统中任务信息 实验源码 …

【虹科】防止PCB组装过程出现质量错误的5种方法

质量问题和错误时有发生,尤其是在涉及PCB和电子产品制造的复杂人为操作任务中。通常情况下,企业可能会配备自动光学检测(AOI)等系统,这些系统通常用于制造过程中“中间”阶段的检测。尽管AOI系统为质量控制创造价值&am…

Jmeter in Linux - 如何在Linux系统使用Jmeter压测?

Jmeter in Linux - 如何在Linux系统使用Jmeter压测?Jmeter in Linux系列目录:1. 在windows创建好一个测试计划:2. 保存后,将jmx后缀的文件上传至Linux服务器3. 执行jmeter命令4. 根据执行日志分析压测报告5. 解析压测报告Jmeter i…

有效的括号-力扣20-java

一、题目描述给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类…

【huggingface系列学习】Using Transformers

文章目录前言Using Transformers使用tokenizer预处理Tokenizer详解Loading and saving加载保存EncodingDecodingModel创建一个Transformer不同的加载方法模型保存使用模型进行推理前言 因实验中遇到很多 huggingface-transformers 模型和操作,因此打算随着 course …

剖析字节案例,火山引擎 A/B 测试 DataTester 如何“嵌入”技术研发流程

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 日前,在 WOT 全球创新技术大会上,火山引擎 DataTester 技术负责人韩云飞做了关于字节跳动 A/B 测试平台的分享。DataTester 是字节跳动内部应…

Roboguide与TIA V16通讯

软件需求:1. roboguide;2. TIA V16;3. KEPServer; 在之前的文章中介绍过KEPServer与TIA V16的通讯,此处不再介绍。接下来,介绍roboguide与KEPServer的仿真通讯。 创建一个roboguide项目。选择【外部设备】➡【添加外部设备】 选择【OPC Server】➡【OK】 OPC服务器名称命…

linux安装并配置nginx

菜鸟教程 一 . Nginx安装和部署 1.输入指令,下载相关的依赖包 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-develYUM(Yellow dog Updater, Modified)为多个Linux发行版的前端软件包管理器 -y 是参数,默认不要确认, rp…

对话 ChatGPT:现象级 AI 应用,将如何阐释「研发效能管理」?

ChatGPT 已然是 2023 开年至今,互联网上最热的话题没有之一。从去年的 AI 图片生成,到 ChatGPT,再到现在各种基于大模型的应用如雨后春笋般出现……在人们探讨技术无限可能的同时,另一个更深刻的命题也不可回避地浮现出来&#xf…

汽摩仪表快检盒

不怕失业 ​ ​最近大火的ChatGPT说要取代程序员,老婆子惊慌失措,跟着糟老头憋屈,咸鱼想靠软件翻身,这下白瞎了。 ​温州寄来了汽车燃油预热控制板,绍兴又寄来了发动机仪表,昆山的尾门在路上,都…

如何成为java架构师?2023版Java架构师学习路线总结完成,真实系统有效,一切尽在其中

导读 从初级Java工程师成长为Java架构师,你需要走很长的路,很多有计划的人在学习之初就在做准备。你知道Java架构师学习路线该怎么走吗?成为一个优秀的Java架构师究竟需要学什么?接下来就跟小编一起揭晓答案。 架构师是一个充满挑战的职业&#xff0…

Python自定义模块

到目前为止,读者已经掌握了导入 Python 标准库并使用其成员(主要是函数)的方法,接下来要解决的问题是,怎样自定义一个模块呢?Python 模块就是 Python 程序,换句话说,只要是 Python 程…

Swagger自动生成api文档

Swagger自动生成api文档Swagger是什么Swagger底层原理使用方式1修改pom文件2启动类中加入注解EnableSwagger23加入SpringFoxConfig.java4加入WebMvcConfig.java文件5 给Web 服务的接口加注解访问可视化页面Swagger是什么 Swagger 是一个规范和完整的框架,用于生成、…

C经典小游戏之扫雷

编译环境:VS022 目录 1.算法思路 2.代码模块 2.1 game.h 2.2 game.cpp 2.3 test.cpp 3.重点分析 4.金句省身 1.算法思路 主要采用二维数组进行实现,设置两个二维数组,一个打印结果,即为游戏界面显示的效果,一个用…

值类型和引用类型

一、值类型和引用类型示例: 值类型:基本数据类型系列,如:int,float,bool,string,数组和结构体等。 引用类型:如:指针,slice切片,map&a…