SpringBoot下Bean的单例模式详解

SpringBoot下Bean的单例模式详解

在 Spring Boot 中,Bean 的单例模式是最常用的管理方式之一。单例模式确保在整个应用程序生命周期中,某个类只有一个实例存在,并且提供一个全局访问点来获取这个实例。Spring Boot 默认将所有的 Bean 设置为单例模式,这意味着无论在哪里请求该 Bean,都会返回同一个实例。本文将详细介绍 Spring Boot 下 Bean 的单例模式,并给出一些错误示例和解决方案。

1. 单例模式详解

1.1 默认单例模式

在 Spring Boot 中,通过 @Component@Service@Repository@Controller 等注解定义的 Bean,默认情况下都是单例模式。这意味着 Spring 容器会确保这些 Bean 在整个应用中只有一个实例。

@Component
public class MyService {public void doSomething() {System.out.println("Doing something...");}
}

1.2 显式设置单例模式

虽然默认情况下 Bean 是单例的,但你也可以显式地设置 Bean 的作用域为单例。这可以通过 @Scope 注解来实现。

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class MyService {public void doSomething() {System.out.println("Doing something...");}
}

2. 单例模式的优势

2.1 资源优化

由于单例模式确保只有一个实例存在,因此可以显著减少内存使用,避免不必要的对象创建和销毁。

2.2 共享状态

单例模式可以方便地在不同的组件之间共享状态信息,例如配置数据或缓存。

2.3 减少重复对象创建的开销

对于需要大量计算或消耗资源创建的对象,单例模式可以显著提高性能。

3. 单例模式的潜在问题

3.1 全局状态管理问题

单例模式的全局状态可能会被不同的客户端代码改变,导致应用的行为难以预测。

3.2 单元测试困难

单例的全局状态使得进行单元测试变得更加困难,因为测试状态可能在测试间共享,无法保证测试的独立性。

3.3 不适合多线程环境

如果单例类没有正确地处理同步机制,可能在多线程环境下导致实例状态的错误。

4. 错误示例及解决方案

4.1 错误示例:在单例 Bean 中使用非线程安全的成员变量

@Component
public class MyService {private int counter = 0;public void incrementCounter() {counter++;}public int getCounter() {return counter;}
}

在这个例子中,counter 是一个非线程安全的成员变量。在多线程环境下,多个线程同时调用 incrementCounter 方法会导致 counter 的值不正确。

解决方案:使用线程安全的数据结构或同步机制
@Component
public class MyService {private AtomicInteger counter = new AtomicInteger(0);public void incrementCounter() {counter.incrementAndGet();}public int getCounter() {return counter.get();}
}

4.2 错误示例:在单例 Bean 中使用线程不安全的第三方库

@Component
public class MyService {private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");public String formatDate(Date date) {return dateFormat.format(date);}
}

SimpleDateFormat 不是线程安全的,因此在多线程环境下使用会导致格式化错误。

解决方案:使用线程局部变量 ThreadLocal
@Component
public class MyService {private final ThreadLocal<SimpleDateFormat> dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));public String formatDate(Date date) {return dateFormat.get().format(date);}
}

5. 单例模式的高级用法

5.1 多个单例 Bean 的管理

在某些情况下,你可能需要从同一个类中创建多个单例 Bean。可以通过在配置类中定义多个 @Bean 方法来实现。

@Configuration
public class AppConfig {@Bean@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)public MyService myService1() {return new MyService();}@Bean@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)public MyService myService2() {return new MyService();}
}

5.2 使用 @Qualifier 注解注入特定的 Bean

当存在多个相同类型的 Bean 时,可以通过 @Qualifier 注解来指定注入哪个 Bean。

@RestController
public class MyController {private final MyService myService1;private final MyService myService2;@Autowiredpublic MyController(@Qualifier("myService1") MyService myService1, @Qualifier("myService2") MyService myService2) {this.myService1 = myService1;this.myService2 = myService2;}@GetMapping("/service1")public String callService1() {return myService1.doSomething();}@GetMapping("/service2")public String callService2() {return myService2.doSomething();}
}

总结

Spring Boot 中的单例模式是确保 Bean 在整个应用生命周期中只有一个实例的有效方法。通过合理使用单例模式,可以优化资源使用、共享状态和减少对象创建的开销。然而,需要注意单例模式在多线程环境下的线程安全问题,并采取相应的措施来确保线程安全。希望本文的介绍和示例能帮助你在 Spring Boot 项目中更好地管理和使用单例模式。

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

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

相关文章

深入FastAPI:路径参数、查询参数及其检校

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年11月学习赛的FastAPI学习总结文档&#xff1b;本文主要讲解路径参数、查询参数及其检校机制。&#x1f495;&#x1f495;&#x1f60a; 介绍 F…

图数据库 | 5、图数据库三大组件之一 之 图计算 (下)

书接上文&#xff1a;图数据库 | 4、图数据库三大组件之一 ——图计算 &#xff08;上&#xff09;-CSDN博客 结合计算效率来评估与设计图计算所需的数据结构。 存储低效性或许是相邻矩阵或关联矩阵等数据结构的最大缺点&#xff0c;尽管它有着O(1)的访问时间复杂度。例如通过…

由播客转向个人定制的音频频道(1)平台搭建

项目的背景 最近开始听喜马拉雅播客的内容&#xff0c;但是发现许多不方便的地方。 休息的时候收听喜马拉雅&#xff0c;但是还需要不断地选择喜马拉雅的内容&#xff0c;比较麻烦&#xff0c;而且黑灯操作反而伤眼睛。 喜马拉雅为代表的播客平台都是VOD 形式的&#xff0…

被抛弃的八股文之keep-alive

还记得在我毕业面试时&#xff0c;经常看到碰到的面试题中都有着TCP中的keep-alive和Http中的keep-alive有什么区别。但是现在的八股文中已经再也见不到了&#xff08;燕子&#xff0c;我们还会再见吗&#xff09; 话说回来&#xff0c;这两个不同的协议中&#xff0c;keep-ali…

衡石分析平台系统分析人员手册-指标管理

指标管理​ 指标平台通过业务主题管理指标&#xff0c;对指标进行授权使用。在指标管理中业务管理员根据业务情况创建相关的主题&#xff0c;将与业务相关的指标添加到主题中&#xff0c;对指标进行上下线管理&#xff0c;将主题及其下面的指标授权给平台内其他用户使用。 本…

【万码优才,等你到来】一款针对程序员求职的平台

hello&#xff0c;大家好我是万码优才推荐官→Aic山鱼&#xff0c;在面对广大程序员找工作的前期我为大家推荐一款超牛的求职平台 ——万码优才 针对当前的求职情况山鱼君也做了一写总结与分析&#xff0c;也结合了其他求职平台给出了“为什么要使用万码优才 这个平台”的原因 …

echarts bar3D画出圆角立方体模拟建筑

结果展示 重点 bar3D中圆角属性&#xff1a;roundCap: true //开启圆角&#xff08;echarts官方文档中没有&#xff09;bevelSize: .6 //圆角程度barSize: 12.5 //立方体大小半球形使用 surface 类型,曲线方程如下 parametricEquation: {u: {min: 0,max: Math.PI,step: Ma…

从建立TRUST到实现FAIR:可持续海洋经济的数据管理

1. 引言 随着我们对信息管理方式的信任&#xff0c;我们的社会对数字化数据的以来呈指数级增长。为了跟上大数据的需求&#xff0c;通过不断的努力和持续实践&#xff0c;对“good”数据管理方式的共识也在不断发展和演变。 加拿大正在建设国家基础设施和服务以及研究数据管理…

CTF-RE 从0到N: perl 逆向

WMCTF2020 easy_re 1.寻找字符串Script 2.通过下一个call 3.将rax的值解析为字符串

RecyclerView详解——(二)优劣,ItemDecoration,SnapHelper

本文主要讲述RecyclerView和ListView的区别&#xff0c;ItemDecoration实现分割线&#xff0c;边距和背景&#xff0c;以及SnapHelper的使用。 一、RecyclerView和ListView 1. 性能和视图重用 ListView 使用的是 ViewHolder 模式来实现视图的重用&#xff0c;但需要手动配置…

[运维][Nginx]Nginx学习(2/5)-Nginx高级

Nginx服务器基础配置实例 前面我们已经对Nginx服务器默认配置文件的结构和涉及的基本指令做了详细的阐述。通过这些指令的合理配置&#xff0c;我们就可以让一台Nginx服务器正常工作&#xff0c;并且提供基本的web服务器功能。 接下来我们将通过一个比较完整和最简单的基础配…

动态规划习题其四【力扣】【算法学习day.26】

前言 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非常非常高滴&am…

candence : 原理图如何导出原理库?

原理图如何导出原理库&#xff1f; 1、打开要需要导出原理图库的工程文件&#xff0c;新建一个原理图库&#xff1a; 2、copy 需要导出的原理图的库文件 3、粘贴到 刚刚新建的原理图库文件中即可 完成 可以一个一个复制&#xff0c;也可以多可一起复制。

二叉树的遍历

普通二叉树的遍历 前序遍历:根 左子树 右子树 中序遍历:左子树 根 右子树 后序遍历:左子树 右子树 根 一颗普通二叉树的实现 #include<stdlib.h> //树的定义 typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTreeNode* left;s…

WebStorm 如何调试 Vue 项目

前言 在日常开发和各种教程中&#xff0c;最常见的 debug 方式就是在代码中插入 console.log 语句&#xff0c;然后在 Chrome 控制台中查看日志。显而易见&#xff0c;插入console.log 的效率不高&#xff0c;那是否有更高效的 debug 方式呢&#xff1f;断点调试允许开发者在代…

timedatectl status显示系统时间相关信息

timedatectl status命令用于显示当前系统的时间和日期相关信息。 下面是每行含义&#xff1a; Local time: 当前系统的本地时间Universal time: 当前系统的协调世界时&#xff08;UTC&#xff09;RTC time: 硬件时钟&#xff08;Real Time Clock&#xff09;的时间Time zone:…

【网页设计】HTML5 和 CSS3 提高

目标 能够说出 3~5 个 HTML5 新增布局和表单标签能够说出 CSS3 的新增特性有哪些 1. HTML5 的新特性 注&#xff1a;该部分所有内容可参考菜鸟教程菜鸟教程 - 学的不仅是技术&#xff0c;更是梦想&#xff01; (runoob.com) HTML5 的新增特性主要是针对于以前的不足&#xf…

09C++结构体

/*结构体属于用户自定义的数据类型&#xff0c; 允许用户存储不同的数据类型, 语法:struct 结构体名{结构体成员列表} ;*/ //struct 结构体名 变量名 #include <iostream> #include <string> using namespace std; struct student { string name; int age;int s…

软件测试之白盒测试(超详细总结)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 白盒测试 白盒测试&#xff08;White Box Testing&#xff09;又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。白盒测试只测试软件产品的内部结…

【入门篇】数字统计——多语言版

题目跳转&#xff1a;数字统计 题目解析&#xff1a; 这道题目要求统计在给定范围 [L, R] 内所有整数中数字 2 出现的次数。例如&#xff0c;在范围 [2, 22] 中&#xff0c;数字 2 分别在数 2、12、20、21、22 中出现的次数&#xff0c;最终出现了6次。 题目的输入为两个正…