当前位置: 首页 > news >正文

Spring中Bean的作用域深入剖析与技术实践

前言

Spring框架作为Java企业级应用开发中的中流砥柱,提供了强大的依赖注入(DI)和面向切面编程(AOP)等功能。在Spring框架中,Bean的作用域(Scope)是一个非常重要的概念,它决定了Bean实例的生命周期和共享方式。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring中Bean的作用域,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。

一、Bean作用域概述

在Spring框架中,Bean的作用域决定了Bean实例在Spring IoC容器中的创建方式、生命周期以及共享方式。Spring支持多种作用域,每种作用域都有其特定的应用场景和生命周期管理策略。

1.1 作用域类型

Spring支持以下五种作用域:

  1. singleton:默认作用域,Spring IoC容器中仅存在一个Bean实例,所有对该Bean的请求都将返回同一个实例。
  2. prototype:每次请求Bean时都会创建一个新的实例,适用于有状态的Bean或需要频繁创建新实例的场景。
  3. request:每次HTTP请求都会创建一个新的Bean实例,仅在当前HTTP请求内有效,适用于Web应用程序。
  4. session:每次HTTP会话都会创建一个新的Bean实例,仅在当前HTTP会话内有效,适用于Web应用程序。
  5. globalSession:类似于session作用域,但仅在Portlet应用程序中使用,用于跨Portlet的会话共享。

1.2 作用域的选择原则

在选择Bean的作用域时,需要考虑以下几个因素:

  • 性能:singleton作用域可以减少对象创建的开销,但需要注意线程安全问题;prototype作用域则每次都会创建新实例,可能导致性能下降。
  • 状态管理:无状态的Bean适合使用singleton作用域,而有状态的Bean则应该使用prototype作用域或其他请求/会话作用域。
  • 应用场景:根据Bean的具体应用场景选择合适的作用域,例如Web应用程序中常用request和session作用域来管理用户的会话状态。

二、Bean作用域的功能点

2.1 Singleton作用域

Singleton作用域是Spring的默认作用域,它保证了在整个应用程序中只有一个Bean实例。这种作用域适用于无状态的Bean,如服务类、工具类等。由于只有一个实例,因此需要注意线程安全问题。

示例代码
java复制代码
@Service
public class MyService {
// 业务逻辑代码
}

在上面的示例中,MyService类被标记为@Service,Spring会自动将其注册为singleton作用域的Bean。

2.2 Prototype作用域

Prototype作用域每次请求都会创建一个新的Bean实例。这种作用域适用于有状态的Bean或需要频繁创建新实例的场景。

示例代码
java复制代码
@Component
@Scope("prototype")
public class MyPrototypeBean {
// 有状态的属性
private String state;
public void setState(String state) {
this.state = state;}
public String getState() {
return state;}
}

在上面的示例中,MyPrototypeBean类被标记为@Component@Scope("prototype"),表示每次请求都会创建一个新的实例。

2.3 Request作用域

Request作用域每次HTTP请求都会创建一个新的Bean实例,仅在当前HTTP请求内有效。这种作用域适用于Web应用程序中需要管理用户请求状态的场景。

示例代码
java复制代码
@Component
@Scope("request")
public class MyRequestBean {
// 请求相关的属性
private String requestData;
public void setRequestData(String requestData) {
this.requestData = requestData;}
public String getRequestData() {
return requestData;}
}

在上面的示例中,MyRequestBean类被标记为@Component@Scope("request"),表示每次HTTP请求都会创建一个新的实例。

2.4 Session作用域

Session作用域每次HTTP会话都会创建一个新的Bean实例,仅在当前HTTP会话内有效。这种作用域适用于Web应用程序中需要管理用户会话状态的场景。

示例代码
java复制代码
@Component
@Scope("session")
public class MySessionBean {
// 会话相关的属性
private String sessionData;
public void setSessionData(String sessionData) {
this.sessionData = sessionData;}
public String getSessionData() {
return sessionData;}
}

在上面的示例中,MySessionBean类被标记为@Component@Scope("session"),表示每次HTTP会话都会创建一个新的实例。

2.5 GlobalSession作用域

GlobalSession作用域类似于session作用域,但仅在Portlet应用程序中使用,用于跨Portlet的会话共享。由于Portlet应用相对较少,因此这种作用域的使用场景也比较有限。

三、Bean作用域的背景

3.1 Spring框架的发展

Spring框架自2002年发布以来,经历了多个版本的迭代和更新。随着Java EE技术的发展和Web应用程序的普及,Spring框架逐渐成为了Java企业级应用开发的首选框架之一。在这个过程中,Bean作用域的概念也逐渐丰富和完善,以适应不同应用场景的需求。

3.2 Web应用程序的需求

在Web应用程序中,用户的状态管理是一个非常重要的问题。为了解决这个问题,Spring框架引入了request和session作用域,使得开发者可以方便地在Web应用程序中管理用户的请求状态和会话状态。随着Web技术的发展和Portlet应用的出现,Spring框架又引入了globalSession作用域来支持跨Portlet的会话共享。

四、Bean作用域的业务点

4.1 数据共享与隔离

不同的作用域决定了Bean实例的共享方式和生命周期。例如,singleton作用域的Bean在整个应用程序中只有一个实例,适用于全局共享的数据;而prototype作用域的Bean每次请求都会创建一个新的实例,适用于需要隔离数据的场景。在Web应用程序中,request和session作用域的Bean则分别用于管理请求级别和会话级别的数据。

4.2 性能优化

Bean作用域的选择对应用程序的性能有很大影响。例如,singleton作用域的Bean可以减少对象创建的开销,提高应用程序的性能;而prototype作用域的Bean则每次请求都会创建新实例,可能导致性能下降。因此,在选择Bean作用域时需要根据具体应用场景进行权衡和优化。

4.3 线程安全

对于singleton作用域的Bean来说,由于整个应用程序中只有一个实例,因此需要注意线程安全问题。如果Bean中存在可变的成员变量并且多个线程同时访问这些变量,就可能导致数据不一致或线程安全问题。为了避免这种问题,可以通过减少可变状态、使用不可变对象或同步代码块等方式来保证线程安全。

五、Bean作用域的底层原理

5.1 Bean的创建过程

在Spring框架中,Bean的创建过程可以分为以下几个步骤:

  1. 解析配置:Spring容器在启动时会解析配置文件或注解,获取Bean的定义信息。
  2. 实例化Bean:根据Bean的定义信息创建Bean的实例。对于singleton作用域的Bean来说,容器会在启动时就创建实例;而对于prototype作用域的Bean来说,则会在每次请求时创建实例。
  3. 设置属性:将Bean的依赖注入到其属性中。
  4. 初始化Bean:调用Bean的初始化方法(如果有的话)。

5.2 Bean的存储与获取

在Spring框架中,Bean实例被存储在IoC容器中。对于singleton作用域的Bean来说,容器会将其存储在一个单例缓存中;而对于prototype作用域的Bean来说,则不会存储在缓存中,每次请求时都会重新创建实例。当需要获取Bean实例时,容器会根据Bean的作用域从相应的存储位置中获取实例。

5.3 Bean的生命周期管理

不同的作用域决定了Bean实例的生命周期管理方式。对于singleton作用域的Bean来说,其生命周期与Spring容器相同,容器启动时创建实例,容器关闭时销毁实例;而对于prototype作用域的Bean来说,其生命周期则由开发者自行管理,每次请求时创建实例,使用完毕后由开发者负责销毁实例(实际上在Java中由垃圾回收器负责销毁)。对于request和session作用域的Bean来说,其生命周期则分别与HTTP请求和HTTP会话的生命周期相同。

六、实践案例与优缺点分析

6.1 实践案例一:单例Bean的管理

场景描述

在一个在线商城系统中,有一个商品服务类ProductService用于处理商品的增删改查操作。由于商品服务类的实例在整个应用程序中只需要一个即可满足需求,因此可以选择将其配置为singleton作用域的Bean。

实现代码
java复制代码
@Service
public class ProductService {
// 商品服务相关的业务逻辑代码
}

在上面的代码中,ProductService类被标记为@Service,Spring会自动将其注册为singleton作用域的Bean。

优缺点分析

优点

  • 性能高:由于整个应用程序中只有一个实例,减少了对象创建的开销。
  • 状态共享:所有请求共享同一个实例,方便数据共享。

缺点

  • 线程安全问题:如果有多个线程同时访问该实例并修改其状态,可能会导致数据不一致或线程安全问题。
  • 灵活性较低:所有请求都复用同一个实例,不适合需要独立实例的场景。

6.2 实践案例二:原型Bean的管理

场景描述

在一个在线支付系统中,每次用户发起支付请求时都需要创建一个新的支付订单对象PaymentOrder。由于每个支付订单都是独立的且需要保持状态信息(如订单金额、支付状态等),因此可以选择将其配置为prototype作用域的Bean。

实现代码
java复制代码
@Component
@Scope("prototype")
public class PaymentOrder {
// 支付订单相关的属性
private double amount;
private String status;
// 省略getter和setter方法
}

在上面的代码中,PaymentOrder类被标记为@Component@Scope("prototype"),表示每次请求都会创建一个新的实例。

优缺点分析

优点

  • 线程安全:每次请求都会创建一个新的实例,避免了多线程间的数据竞争问题。
  • 灵活性高:适合需要独立实例或有状态Bean的场景。

缺点

  • 性能开销:频繁创建和销毁实例可能导致性能下降。
  • 生命周期管理:需要开发者手动管理Bean的创建和销毁(实际上在Java中由垃圾回收器负责销毁),增加了编程复杂度。

6.3 实践案例三:请求作用域Bean的管理

场景描述

在一个Web应用程序中,需要记录用户的登录信息以便在请求处理过程中使用。由于登录信息只需要在当前HTTP请求内有效,因此可以选择将其配置为request作用域的Bean。

实现代码
java复制代码
@Component
@Scope("request")
public class UserLoginInfo {
// 用户登录信息相关的属性
private String username;
private String sessionId;
// 省略getter和setter方法
}

在上面的代码中,UserLoginInfo类被标记为@Component@Scope("request"),表示每次HTTP请求都会创建一个新的实例。

优缺点分析

优点

  • 线程安全:每个HTTP请求都会创建一个新的实例,天然地隔离了请求之间的状态。
  • 资源节约:请求结束后自动销毁实例,避免了不必要的资源占用。

缺点

  • 适用范围限制:仅适用于Web应用程序且需要特定的Servlet容器支持。
  • 生命周期短:仅在请求生命周期内有效,对于跨请求的数据管理不适用。

6.4 实践案例四:会话作用域Bean的管理

场景描述

在一个购物车系统中,需要记录用户的购物车信息以便在用户会话期间内持续有效。由于购物车信息需要在整个HTTP会话期间内有效且需要保持状态信息(如商品列表、总价等),因此可以选择将其配置为session作用域的Bean。

实现代码
java复制代码
@Component
@Scope("session")
public class ShoppingCart {
// 购物车相关的属性
private List<Product> products = new ArrayList<>();
private double totalPrice;
// 省略getter和setter方法以及业务逻辑代码
}

在上面的代码中,ShoppingCart类被标记为@Component@Scope("session"),表示每个HTTP会话都会创建一个新的实例。

优缺点分析

优点

  • 持久化会话状态:每个用户会话创建一个实例,可以用来保存会话级别的数据。
  • 线程安全:每个用户拥有独立的实例避免了并发冲突。

缺点

  • 资源消耗:长时间的会话可能导致内存占用增加。
  • 适用范围限制:同样局限于Web应用且依赖于会话管理机制。

七、总结与展望

通过本文的深入剖析和技术实践展示,我们可以对Spring中Bean的作用域有一个全新的认识。不同的作用域决定了Bean实例的创建方式、生命周期以及共享方式,对于优化应用性能、管理资源和确保线程安全至关重要。在未来的发展中,随着Java EE技术和Web应用程序的不断演进,Spring框架中的Bean作用域概念也将继续丰富和完善以适应更多应用场景的需求。作为开发者我们需要不断学习和掌握这些新技术以提升自己的竞争力并为企业创造更大的价值。

相关文章:

Spring中Bean的作用域深入剖析与技术实践

前言 Spring框架作为Java企业级应用开发中的中流砥柱&#xff0c;提供了强大的依赖注入&#xff08;DI&#xff09;和面向切面编程&#xff08;AOP&#xff09;等功能。在Spring框架中&#xff0c;Bean的作用域&#xff08;Scope&#xff09;是一个非常重要的概念&#xff0c;…...

Python爬虫实战:抓取拼多多商品详情数据(基于pdd.item_get接口)

在当前的电商市场中&#xff0c;拼多多以其独特的拼团模式和优惠价格吸引了大量用户&#xff0c;成为继淘宝、京东之后的又一大电商平台。对于数据分析和市场研究者来说&#xff0c;获取拼多多的商品详情数据显得尤为重要。本文将介绍如何使用Python爬虫技术&#xff0c;通过调…...

工具类-列表请求工具 useList

useList 用于列表请求的基于 vue 3 的 hooks&#xff0c;接收请求函数、请求参数等数据&#xff0c;自动生成请求请求函数&#xff0c;分页信息等 本文有涉及到 http 请求工具和接口返回格式的内容&#xff1a; http 工具&#xff1a;一个基于 axios 封装的请求工具Response…...

Scala中的正则表达式01

规则类型具体规则示例说明单字符大多数字符匹配自身正则表达式 abc&#xff0c;文本 abca 匹配 a&#xff0c;b 匹配 b&#xff0c;c 匹配 c方括号 [ ][ ] 定义字符集&#xff0c;匹配其一[abc]&#xff0c;文本 a、b 或 c[abc] 匹配 a、b 或者 c排除字符集 [^ ][^ ] 开头加 ^&…...

基于SpringBoot的养老院管理系统的设计与实现

一、前言 随着人口老龄化的加剧&#xff0c;养老院作为老年人养老的重要场所&#xff0c;其管理的高效性和科学性显得尤为重要。传统的养老院管理方式多依赖人工操作&#xff0c;存在信息记录不及时、不准确&#xff0c;管理流程繁琐&#xff0c;资源调配困难等问题。利用信息技…...

Ansible变量详解(变量定义+变量优先级+变量注册+层级定义变量+facts缓存变量)

本篇文章详细给大家介绍Ansible变量&#xff0c;变量适合管理剧本中每个项目的动态值&#xff0c;或是某些值在多个地方重复使用&#xff0c;如果将此值设置为变量再在其他地方调用会方便许多。会用变量&#xff0c;才算真正会用Ansible&#xff0c;话不多说&#xff0c;直接开…...

面向对象系统的分析和设计

来源&#xff1a;《设计模式精解-GOF23种设计模式解析》 作者&#xff1a;k_eckel k_eckels mindview - 博客园 (cnblogs.com) --------- 面向对象系统的分析和设计实际上追求的就是两点&#xff1a; &#xff08;1&#xff09;高内聚 &#xff08;2&#xff09;低耦合 …...

Vue 提供了Transition,可以帮助你制作基于状态变化的过渡和动画

官方文档&#xff1a;https://cn.vuejs.org/guide/built-ins/transition.html Transition​ Vue 提供了两个内置组件&#xff0c;可以帮助你制作基于状态变化的过渡和动画&#xff1a; <Transition> 会在一个元素或组件进入和离开 DOM 时应用动画。本章节会介绍如何使用…...

视频编辑技术:一键生成混剪视频的AI技术应用

随着视频内容的爆炸式增长&#xff0c;视频编辑技术也在不断进步。本文将探讨如何利用AI技术&#xff0c;实现一键生成混剪视频&#xff0c;并自动添加配音和字幕&#xff0c;以提高视频编辑的效率和质量。 AI技术在视频编辑中的应用 AI技术在视频编辑领域的应用越来越广泛&am…...

Android11 MTK 开机默认启动热点

1、需求&#xff1a;开机后不锁屏&#xff0c;默认打开热点&#xff0c;且长时间没有设备连接热点时保证热点也是打开的。 2、开机后不锁屏&#xff1a; 路径&#xff1a;vendor/mediatek/proprietary/packages/apps/SettingsProvider/res/values/defaults.xml<bool name&q…...

Vue Web开发(二)

1. 项目搭建 1.1. 首页架子搭建 使用Element ui中的Container布局容器&#xff0c;选择倒数第二个样式&#xff0c;将代码复制到Home.vue。 1.1.1.下载less &#xff08;1&#xff09;下载less样式 npm i less   &#xff08;2&#xff09;下载less编辑解析器 npm i less…...

Linux-实用操作

文章目录 一. 各类实用小技巧(快捷键)1. ctrl c 强制停止2. ctrl d 退出登出3. history 查看历史命令4. !命令前缀&#xff0c;自动匹配上一个命令5. ctrl r&#xff0c;搜索历史命令6. ctrl a | e&#xff0c;光标移动到命令开始或结束7. ctrl ← | →&#xff0c;左右跳…...

Elasticsearch:使用 Elastic APM 监控 Android 应用程序

一、前言 人们通过私人和专业的移动应用程序在智能手机上处理越来越多的事情。 拥有成千上万甚至数百万的用户&#xff0c;确保出色的性能和可靠性是移动应用程序和相关后端服务的提供商和运营商面临的主要挑战。 了解移动应用程序的行为、崩溃的发生和类型、响应时间慢的根本…...

Go的简单问题问答

基础问题回答 Go 的主要特点是什么&#xff1f; 简洁&#xff1a;语法简化&#xff0c;减少复杂性。并发&#xff1a;内置 Goroutine 和 Channel&#xff0c;支持轻量级并发。静态类型&#xff1a;强类型语言&#xff0c;编译时检查错误。跨平台&#xff1a;编译生成独立的二进…...

【攻防实验】溯源与取证分析实验

溯源与取证分析实验 溯源取证分析作为网络攻防过程中重要环节&#xff0c;准确找到攻击者的入侵线索(尤其是攻击突破口、攻击IP地址、域名、工具等信息)&#xff0c;对于企业或者团队安全运营团队来说都是必备技能。常规攻击取证过程中往往会结合流量、Web访问日志、终端系统或…...

THREE.js 入门(一)xyz坐标系

一、坐标系概念 在 three.js 中&#xff0c;相机的默认朝向是沿着 Z 轴的负方向。也就是说&#xff0c;默认情况下&#xff0c;相机会沿着 Z 轴的负方向“看”到场景中的对象&#xff0c;而 X 轴和 Y 轴分别对应水平方向和垂直方向。换句话说&#xff0c;相机的默认位置是 (0,…...

AUTOSAR CP中基于通信模块(COM)的Transformer-R24的规范导读

该文档是关于 AUTOSAR CP中基于通信模块&#xff08;COM&#xff09;的Transformer的规范说明&#xff0c;主要内容包括引言、相关文档、约束与假设、功能规范、API 规范、配置规范等&#xff0c;旨在为汽车电子系统开发中基于 COM 的Transformer提供全面的技术规范和指导。 一…...

ubuntu20.04安装anygrasp_sdk

ubuntu20.04安装anygrasp_sdk采坑记录 安装ME的教程看上一篇,现在来看anygrasp安装问题grasp_detection、grasp_trackinglicense申请demo文件的运行注意的地方到这以为大功告成了,然后出现了一个numpy版本不匹配问题最后还有一个问题就是修改demo.sh,不然没法可视化结果展示安…...

Spring完整知识点二

Spring注解开发 Spring是轻代码而重配置的框架&#xff0c;配置比较繁重&#xff0c;影响开发效率&#xff0c;所以注解开发是一种趋势&#xff0c;它能够代替xml配置文件&#xff0c;可以简化配置&#xff0c;提高开发效率Spring注解根据出现时间分类 Spring原始注解&#xf…...

GESP三级集训——课堂笔记(部分)

进制转换&#xff08;二进制、十进制、八进制、十六进制等&#xff09; 十进制&#xff08;逢十进一&#xff09;——Decimal 十进制是我们生活中最常见的进制&#xff0c;如“1”“23”“891”等&#xff1a; 进位过程如下&#xff1a;{1,2,3,4,5,6,7,8,9}{10,11,12,13,14,…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...