Spring - Bean的6种作用域

news2024/9/27 19:18:23

  • 1、Bean作用域问题
    • 2、作用域定义
    • 2.1、Bean的6种作用域
      • singleton 单例模式
      • prototype 原型作用域
      • request 请求作用域
      • session 会话作用域
      • application 全局作用域(了解)
      • websocket
    • 单例作用域 vs 全局作用域
  • 2.设置作用域

1、Bean作用域问题

通过一个案例来看Bean的作用域。假设有一个公共的Bean对象,提供给A类和B类使用,然而在A类使用的过程中,修改了Bean的数据,导致B类在使用Bean的时候产生了预期之外的逻辑错误。

预期结果是公共Bean可以在各自类中被修改,但不能影响其他类使用(使用时还是Bean的初始数据)。

公共Bean:

@Component
public class Users {
    @Bean
    public User user1(){
        User user = new User();
        user.setName("zhangsan");//注意 初始化为 zhangsan
        user.setId(1);
        return user;
    }
}

User对象:

public class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

A类使用时,修改了数据:把name修改成了Lisi

@Controller
public class AController {
    @Autowired
    private User user;
    public User getUser1(){
        System.out.println("Bean 原 name :"+user.getName());
        user.setName("Lisi");//A类修改了Bean原生数据
        return user;
    }
}

B类再去使用公共Bean时:

@Controller
public class BController {
    @Autowired
    private User user1;

    public User getUser1(){
        User user = user1;
        return user;
    }
}

打印A和B类使用公共Bean 的值:

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.config.xml");
        
        AController aController = context.getBean(AController.class);
        System.out.println("A类修改后 name :"+aController.getUser1().toString());
        
        BController bController = context.getBean(BController.class);
        System.out.println("B读取到的 name :"+bController.getUser1().toString());
    }
}

运行结果:

在这里插入图片描述

原因分析:

以上运行结果的原因是:因为Bean默认情况下是单例模式(singleton),也就是所有人使用的都是同一个Bean对象。因为使用单例模式可以很大程度上提高性能,所以在spring中Bean的作用域默认也是singleton单例模式。

2、作用域定义

程序中变量的可用范围就叫做作用域,或者说在源代码中定义某个变量在某个区域就叫做作用域。而Bean的作用域是指Bean在Spring整个框架中的某种行为模式,比如singleton单例作用域,就表示Bean在spring中只有一份,全局共享的,当A修改了这个值后,那么B再使用时就是修改后的值。

2.1、Bean的6种作用域

Spring容器在初始化一个Bean对象时,会指定该实例的作用域。spring有6种作用域,最后4种是基于Spring MVC生效的:

1.  singleton:单例模式
2.  prototype:原型作用域(多例作用域)
3.  request:请求作用域
4.  session:会话作用域
5.  application:全局作用域
6.  websocket:HTTP  WebSocket 作用域

注意后4种是SpringMVC中的值,在普通的Spring项目中只有前两种。

singleton 单例模式

  • 该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过 applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对象。
  • 场景:通常⽆状态的Bean使⽤该作⽤域。⽆状态表示Bean对象的属性状态不需要更新。
  • 备注:Spring默认选择该作⽤域。

prototype 原型作用域

  • 描述:每次对该作用域下的Bean的请求都会创建一个新的实例:获取Bean(即通过 applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同新的对象。
  • 场景:通常有状态的Bean使用该作用域。

request 请求作用域

  • 描述:每次http请求会创建新的Bean实例,类似于prototype
  • 场景:⼀次http的请求和响应的共享Bean
  • ⼀次http的请求和响应的共享Bean

session 会话作用域

  • 描述:在⼀个http session中,定义⼀个Bean实例

  • 场景:⽤户回话的共享Bean, ⽐如:记录⼀个⽤户的登陆信息

    备。

  • 备注:限定SpringMVC中使⽤

application 全局作用域(了解)

  • 描述:在⼀个http servlet Context中,定义⼀个Bean实例。
  • 场景:Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息。
  • 备注:限定SpringMVC中使⽤。

websocket

  • 描述:在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例。
  • 场景:WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,知道WebSocket结束都是同一个Bean。
  • 备注:限定Spring WebSocket中使⽤。

单例作用域 vs 全局作用域

  • singleton 是 Spring Core 的作⽤域;application 是 Spring Web 中的作⽤域;
  • singleton 作⽤于 IoC 的容器,⽽ application 作⽤于 Servlet 容器。

2.设置作用域

@Scope既可以修饰方法也可以修饰类

  1. 使用@Scope标签设置Bean的作用域: 设置为 prototype 全局作用域
@Component
public class Users {
    @Scope("prototype")//设置为 prototype 全局作用域
    @Bean
    public User user1(){
        User user = new User();
        user.setName("zhangsan");//注意 初始化为 zhangsan
        user.setId(1);
        return user;
    }
}

运行结果:此时A修改数据,不会影响B读取的数据。

在这里插入图片描述

  1. 使用枚举设置@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
public class Users {
    //@Scope("prototype")
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    @Bean
    public User user1(){
        User user = new User();
        user.setName("zhangsan");//注意 初始化为 zhangsan
        user.setId(1);
        return user;
    }
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6TiFDyiP-1686991444637)(C:\Users\COFFEEWEN\AppData\Roaming\Typora\typora-user-images\image-20230616150256693.png)]

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

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

相关文章

[工业互联-10]:PLC入门简介

目录 前言 PLC的用途 PLC的特点 PLC的分类 1、按PLC的控制规模分类 2、按PLC的控制性能分类 3、按PLC的结构分类 PLC的技术指标 1、硬件指标 2、软件指标 3、主要性能指标介绍 1) 存储容量 2) 输入/输出(I/O)点数 3) 扫描速度 4) 指令的功…

【Redis】五种数据结构

在内存种种存储形式如下:

练习2:逻辑回归

练习2:逻辑回归 介绍 在本练习中,您将实现逻辑回归并将其应用于两个不同的数据集。还将通过将正则化加入训练算法,来提高算法的鲁棒性,并用更复杂的情形来测试模型算法。 在开始练习前,需要下载如下的文件进行数据上…

90后程序员回家卖羊粪,月销售额120万!

不得不说,程序员是一个勤奋而又善于思考的群体。他们不只是代码写得好,善于逻辑思维,即使有一天不做程序员,转行其他岗位了,也能在新的岗位上面玩出花样。 早在2013年的时候,就有一位新浪的PHP程序员转行卖…

单点登录:CAS使用springboot main方法启动cas-server

1.下载demo git clone https://gitee.com/pelin0963/cas-server.git2.使用eclipse导入maven项目。此次我是用的spring tool suite 4导入的。 导入时会用较长时间,10分钟吧。需要下载很多资源。 3.报错,提示缺少jar包 Missing artifact net.shibbolet…

【java】使用 BeanUtils.copyProperties 11个坑(注意事项)

文章目录 背景第1个坑: 类型不匹配第2个坑: BeanUtils.copyProperties是浅拷贝第3个坑:属性名称不一致第4个坑:Null 值覆盖第5个坑:注意引入的包第6个坑:Boolean类型数据is属性开头的坑第7个坑:查找不到字段…

C语言strlen函数的缺陷与实现,strcpy函数的缺陷与实现,strcat函数的缺陷与实现,strcmp的实现。

1.strlen 函数原型: size_t strlen( const char *string );size_t 是无符号整型,相当于unsigned intconst char *string 是目标字符串 函数作用: 计算字符串的长度。 函数的模拟实现: size_t _strlen(const char * str) {ass…

地址解析省市区详细地址

项目代码源地址在我的github:https://github.com/weitw/address-analyzer 一、项目介绍 1、解析规则 将一个用户输入的地址,解析成省、市、区、详细地址的形式。 如果用户输入的不是标准的地址,则需要推测标准地址。例如用户输入&#xff…

【AIGC】16、Vision-Language 模型在视觉任务中的调研

文章目录 一、简介二、基础知识2.1 视觉任务的训练策略2.2 VLM 基础2.2.1 网络结构2.2.2 预训练目标函数2.2.3 评估和下游任务 2.3 数据集 三、迁移学习3.1 使用 prompt tuning 实现迁移学习3.2 通过特征适应来进行迁移学习 四、VLM 的知识蒸馏4.1 目标检测的知识蒸馏4.2 语义分…

用雪花 id 和 uuid 做 MySQL 主键,被领导怼了

在MySQL中设计表的时候,MySQL官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究竟有什么坏处?本篇…

打造专属封面!这两款神器必备

无论你是图文博主还是视频博主,做封面都是必不可少的。谈及可制作封面的工具,种类是极其繁多的,比如黄油相机、美图秀秀、美易等。虽然这些工具各有千秋,但我不建议使用,因为它们的某个功能可能做得不错,但…

【MySQL数据库 | 第十九篇】SQL性能分析工具

目录 前言: SQL执行频率: 慢查询日志: profile: profile各个指令: 总结: 前言: 本篇我们将为大家讲解SQL性能的分析工具,而只有熟练的掌握了性能分析的工具,才可以更…

JVM知识点整理

JVM 回收哪个区域?关联面试题:fullgc会回收方法区(元空间)吗? 怎么判断对象可以被回收了关联面试题:哪些对象可以作为 GC Root (两栈两方法) JVM GC什么时候执行?分代回收机制思考&…

pandas---文件读取与存储(csv、hdf、json、excel、sql)

数据大部分存在于文件当中,所以pandas会支持复杂的IO操作,pandas的API支持众多的文件格 式,如CSV、SQL、EXCEL、JSON、 HDF5。 1. csv文件 pandas.read_csv(filepath_or_buffer, sep ,, usecols ) filepath_or_buffer:文件路径 sep :…

简要介绍 | 强化学习:从原理到应用

注1:本文系“简要介绍”系列之一,仅从概念上对强化学习进行非常简要的介绍,不适合用于深入和详细的了解。 注2:"简要介绍"系列的所有创作均使用了AIGC工具辅助 强化学习:从原理到应用 1. 背景介绍 强化学习…

手撕学生管理系统超详解——【c++】

题目要求:设计一个学生成绩管理程序,实现按班级完成对学生成绩信息的录入和修改,并用文件保存。 实现按班级输出学生的成绩单;实现按学号和姓名进行查询,按平均成绩进行排序功能。 问题描述 该程序的目标是提供一个简单且易于使用…

scratch lenet(2): C语言实现图像直方图的计算

scratch lenet(2): C语言实现图像直方图的计算 1. 目的 用 C 语言实现 uint8 类型图像(单通道)的直方图计算。不涉及直方图均衡化。 2. 什么是图像直方图 2.1 统计得到图像直方图 通常是对于单通道的灰度图而言的。像素范围是 [0, 255], 统计每个像…

提高错误日志处理效率!使用Python和钉钉机器人实现自动告警聚合

1、背景 日志是非常重要的信息资源。它们记录了应用程序的运行状态、错误和异常情况,帮助我们了解系统的健康状况以及发现潜在的问题。为了高效地管理和分析日志数据,许多组织采用了Elasticsearch、Logstash和Kibana(ELK)堆栈作为…

Eclipse Krazo(Jakarta MVC)的使用

文章目录 背景Jakarta MVC规范Eclipse Krazo使用前的思考全局配置Controller示例返回View的三种写法View中用到的Model如何设值?View中如何获取Model中的值? 参数校验防止CSRFKrazo是如何实现的呢?如何生成csrf的token?如何校验cs…

开源赋能,决胜未来 — 参加原子全球开源峰会有感

目录 文章目录 目录前言开源决胜未来:闭源摧毁 UNIX,开源成就 Linux开源创新:软硬件协同,共建开源生态 前言 开源原子基金会作为国内首家开源基金会组织,由其主办的首届 “开放原子全球开源峰会” 也是第一次被冠以 “…