Spring - Bean的6种作用域

news/2024/11/18 4:28:46/

  • 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 {@Beanpublic User user1(){User user = new User();user.setName("zhangsan");//注意 初始化为 zhangsanuser.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;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +'}';}
}

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

@Controller
public class AController {@Autowiredprivate 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 {@Autowiredprivate 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 全局作用域@Beanpublic User user1(){User user = new User();user.setName("zhangsan");//注意 初始化为 zhangsanuser.setId(1);return user;}
}

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

在这里插入图片描述

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

运行结果:

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


http://www.ppmy.cn/news/438148.html

相关文章

UE4--局域网多人联机

文章目录 前言一、UI界面的创建1.三个UI2.主界面3.查找界面4.加入界面 二.基于UI界面蓝图的创建1.主界面的蓝图2.查找界面蓝图3.加入界面蓝图 三、实现联网的前提(不能出错)1.创建两个变量(加入界面蓝图里创建)2.关卡蓝图3.创建第…

winkawaks1.45如何联机?winkawaks1.45怎样联机对战(其他版本类似)

《winkawaks1.45如何联机?winkawaks1.45怎样联机对战》是街机中国小编为大家汇集整理的winkawaks攻略,很多小伙伴还有winkawaks1.45如何联机?winkawaks1.45怎样联机对战的疑问,一起来看看吧。 下面的下载地址就是他了http://www.kaillera.com/download…

Vue练手项目之仿京东到家主页

目录 概述1.效果展示2.使用原始HtmlCSS实现3.使用Vue.js进行组件化3.1 Header部分组件实现3.1.1图标的展示3.1.2 定义Vue调试的名称3.1.3 使用scoped隔离组件间的css影响 3.2 附近店铺部分实现3.3 底部导航栏组件的实现3.4 将组件组成一个整体页面 4.代码地址 概述 本人是一个…

C++:基础知识

struct和class的区别 structclass相同点 两者都拥有成员函数、公有和私有部分任何可以使用class完成的工作,同样可以使用struct完成不同点struct默认是public继承class默认是private继承 final和override关键字 当不希望某个类被继承,或不希望某个虚函…

风电光伏iEEE33节点蒙特卡洛概率潮流计算

基于蒙特卡洛法的概率潮流 以IEEE33节点的电网为研究对象 建立了光伏和风电的概率出力模型 采用蒙特卡洛法进行随机抽样 之后基于抽样序列进行概率潮流计算 最后得到电网的电压概率出力曲线

visual studio装在哪个盘比较好_燃气热水器,装在哪里更合适?

燃气热水器,它肩负了一家人的洗手、洗澡等热水供应重任,是多数现代家庭装修必备的一件电器,由于安装位置的特殊要求、且它的尺寸也是相对较大,因此在家里哪个位置安装燃气热水器,也是一个考究设计与实用兼顾的细节了。…

英特尔显卡不支持自定义分辨率N卡解决办法

本文参考bilibili“Peepoodo今天吃什么”UP主的“关于天选CSGO等机子没有独显直连自定义分辨率的问题”作品。 我的是N卡,A卡可以去UP主那里看教程https://www.bilibili.com/video/BV1XV41147SR?share_sourcecopy_web 最新版N卡不支持自定义分辨率,之前…

仿淘宝购物车

** 效果图 ** 配置 <uses-permission android:name"android.permission.INTERNET"/> <applicationandroid:name"app.MyApp">gradle implementation com.squareup.okhttp3:okhttp:3.12.0 implementation com.google.code.gson:gson:2.2.4 im…