探究Spring的单例设计模式--单例Bean
Spring的单例设计模式
在Spring框架中,单例设计模式是一种常见且重要的设计模式,主要用于确保在应用程序的生命周期中仅创建一个特定的Bean实例
一、什么是单例设计模式?
单例设计模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。这种模式的核心在于控制实例的创建,避免了因为多次创建对象导致的资源浪费。单例模式通常用于以下场景:
-
节约资源:在需要大量创建相同对象时,使用单例可以显著减少内存消耗。
-
全局访问:单例模式提供了一个全局访问点,使得在任何地方都能轻松获取到该实例,避免了需要通过参数传递对象的复杂性。
-
协调操作:在某些情况下,多个对象需要共享状态或资源,单例模式能够确保所有对象都访问到相同的数据。
在Spring框架中,单例Bean是默认的Bean作用域。开发者定义的Bean如果没有显式指定作用域,Spring容器将自动将其视为单例。Spring通过内置的机制管理单例Bean的创建和访问,确保应用在运行时始终只有一个实例。
这种设计模式使得Spring的开发者可以专注于业务逻辑,而不必担心实例化和管理对象的细节。Spring通过依赖注入(DI)机制,将单例Bean的实例注入到需要它的类中,提供了简单而强大的方式来共享对象。
二、Spring中的单例Bean
在Spring中,当我们定义一个Bean时,如果没有指定作用域,它默认是单例的。以下是一个简单的示例:
import org.springframework.stereotype.Component;@Component
public class MySingletonBean {public MySingletonBean() {System.out.println("MySingletonBean instance created");}public void doSomething() {System.out.println("Doing something...");}
}
在这个示例中,MySingletonBean是一个单例Bean。当Spring容器启动时,它会创建这个Bean的唯一实例。
三、单例Bean的实现原理
在Spring框架中,单例Bean的实现依赖于Spring容器的管理机制:
1.单例Bean的创建
Spring容器负责Bean的实例化、配置和生命周期管理。单例Bean的创建主要在AbstractAutowireCapableBeanFactory类中进行。具体的创建流程如下:
-
Bean定义的注册:首先,在Spring容器启动时,所有的Bean定义(包括其元数据)会被注册到
DefaultListableBeanFactory中。 -
Bean的实例化:当一个Bean被请求时,Spring会检查是否已经存在该Bean的实例。对于单例Bean,Spring在第一次请求时会创建实例,并将其存储在缓存中。
2.源码解析
下面是Spring源码中与单例Bean管理相关的几个重要部分:
3.单例Bean的生命周期管理
除了实例化,Spring还负责单例Bean的生命周期管理,包括:
初始化:Bean被实例化后,可以执行初始化方法,例如通过@PostConstruct注解或实现InitializingBean接口。
销毁:在容器关闭时,Spring会调用单例Bean的销毁方法,例如通过@PreDestroy注解或实现DisposableBean接口。
-
Bean的创建逻辑:在
AbstractAutowireCapableBeanFactory中,doGetBean方法负责获取Bean实例。以下是部分代码片段:@Override protected <T> T doGetBean(String name, Class<T> requiredType, Object[] args) {// 检查缓存Object bean = getSingleton(name);if (bean != null) {return (T) bean;}// 如果缓存中不存在,则创建新实例// 省略 Bean 实例化逻辑bean = createBean(name, mbd, args);// 将创建的 Bean 存入缓存registerSingleton(name, bean);return (T) bean; } public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "'beanName' must not be null");synchronized (this.singletonObjects) {// 检查缓存中是否存在实例Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {//...省略了很多代码try {singletonObject = singletonFactory.getObject();}//...省略了很多代码// 如果实例对象在不存在,我们注册到单例注册表中。addSingleton(beanName, singletonObject);}return (singletonObject != NULL_OBJECT ? singletonObject : null);}}//将对象添加到单例注册表protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));}} }getSingleton(name):检查是否存在该Bean的实例。createBean(name, mbd, args):创建新的Bean实例。registerSingleton(name, bean):将新创建的Bean注册到单例缓存中。
-
单例缓存:Spring使用
singletonObjects集合来缓存单例Bean实例,具体在DefaultSingletonBeanRegistry中定义:protected final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);- 当一个单例Bean被创建后,Spring会将其实例存储在这个
singletonObjects映射中,以便后续请求时直接返回。
- 当一个单例Bean被创建后,Spring会将其实例存储在这个
-
线程安全:Spring确保单例Bean在多线程环境中的安全性。对于单例Bean的创建,通常会在关键部分添加同步机制,以防止多个线程同时创建实例。例如,在创建单例Bean时,Spring会使用
synchronized关键字来保证线程安全。
四、总结
Spring的单例设计模式通过确保Bean在整个应用程序中只有一个实例,提供了高效的资源管理和简化的访问方式。理解单例Bean的实现原理及其在多线程环境中的安全性,对于开发高效的Spring应用至关重要。
相关文章:
探究Spring的单例设计模式--单例Bean
Spring的单例设计模式 在Spring框架中,单例设计模式是一种常见且重要的设计模式,主要用于确保在应用程序的生命周期中仅创建一个特定的Bean实例 一、什么是单例设计模式? 单例设计模式是一种创建型设计模式,确保一个类只有一个…...
js基础速成-Set、Map
集合(Set) 集合是元素的集合,只能包含唯一元素 创建一个空集合 const companies new Set() console.log(companies)Set(0) {}从数组创建集合 const languages [英语,芬兰语,英语,法语,西班牙语,英语,法语, ]const setOfLanguages new …...
手机软件何时统一——桥接模式
文章目录 手机软件何时统一——桥接模式凭什么你的游戏我不能玩紧耦合的程序演化合成/聚合复用原则松耦合的程序桥接模式桥接模式基本代码 手机软件何时统一——桥接模式 凭什么你的游戏我不能玩 时间:5月31日20点 地点:大鸟房间 人物…...
【Nacos 架构 原理】服务发现模块之Nacos注册中心服务数据模型
文章目录 服务(Service)和服务实例(Instance)定义服务服务元数据定义实例实例元数据持久化属性 集群定义集群 生命周期服务的生命周期实例的生命周期集群的生命周期元数据的生命周期 服务(Service)和服务实…...
基于微信小程序爱心领养小程序设计与实现(源码+参考文档+定制开发)
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...
【数据库】 MongoDB 用户分配新的角色和权限
在 MongoDB 中,可以通过简单的命令为用户分配新的角色和权限。这对于调整用户的访问能力和管理数据库安全至关重要。以下是如何为用户分配新的角色和权限的详细步骤。 1. 使用 MongoDB Shell 分配角色 1.1 修改用户角色 要为现有用户分配新的角色,可以…...
加速 Python for 循环
在 Python 编程中,for 循环是开发者常用的工具之一,但它的执行速度经常让人感到不满。幸运的是,有许多方法可以显著提高 for 循环的效率。 本文将介绍几种简单而高效的优化技巧,帮助你加速Python for 循环,速度提升从…...
计算机毕业设计 基于Python国潮男装微博评论数据分析系统的设计与实现 Django+Vue 前后端分离 附源码 讲解 文档
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...
React 表单与事件
React 表单与事件 React 是一个用于构建用户界面的 JavaScript 库,它通过组件化的方式来提高开发效率和代码的可维护性。在 React 应用中,表单和事件处理是核心功能之一,它们允许用户与应用程序进行交互。本文将深入探讨 React 中的表单处理…...
Appium独立测试自动化初始化脚本
1、查看环境初始化参数 确保appium已经开起来了,设置ip ,并点击启动 打开夜神模拟器,点击工具--设置 最下面的版本说明,双击进去 版本号这里再去单击。 直到进入到开发者模式。 可能我们不是开发者模式打开的状态,所以软件访问模…...
Nginx反向代理配置支持websocket
一、官方文档 WebSocket proxying 为了将客户端和服务器之间的连接从HTTP/1.1转换为WebSocket,使用了HTTP/1.1中可用的协议切换机制(RFC 2616: Hypertext Transfer Protocol – HTTP/1.1)。 然而,这里有一个微妙之处:由于“升级”…...
C# 游戏引擎中的协程
前言 书接上回,我谈到了Unity中的协程的重要性,虽然协程不是游戏开发“必要的”,但是它可以在很多地方发挥优势。 为了在Godot找回熟悉的Unity协程开发手感,不得不自己做一个协程系统,幸运的是,有了Unity的…...
如何封装微信小程序中的图片上传功能
文章目录 前言一、需求分析与设计思路二、上传图片功能封装三、页面调用示例四、功能改进与扩展4.1 压缩图片4.2 上传进度4.3 重试机制 五、总结 前言 在微信小程序开发中,图片上传功能是一个十分常见的需求,不管是社交分享、商城中的商品图片上传&…...
被问界/理想赶超!奔驰CEO再度“出马”,寻找中国外援
来自中国车企的全方位、持续施压,让大部分外资车企开始寻求更多的本地化合作来实现技术升级。传统豪华品牌也同样如此。 本周,知情人士透露,梅赛德斯奔驰首席执行官Ola Kllenius计划再次访问中国,目的是进一步寻求和扩大与本地技术…...
魔改xjar支持springboot3,
jar包加密方案xjar, 不支持springboot3。这个发个魔改文章希望大家支持 最近公司需要将项目部署在第三方服务器,于是就有了jar包加密的需求,了解了下目前加密方案现况如下: 混淆方案,就是在代码中添加大量伪代码,以便隐藏业务代…...
python json文件读写
在Python中处理JSON文件是一个常见的任务。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。Python提供了内置的json模块来帮助我们读取和写入JSON格式的数据。 如何读…...
Android常用C++特性之std::find_if
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。 std::find_if 是 C 标准库中的一个算法,用于在给定范围内查找第一个满足特定条件的元素。它接受一个范围(由迭代器指定)和一个谓词…...
19 vue3之自定义指令Directive按钮鉴权
directive-自定义指令(属于破坏性更新) Vue中有v-if,v-for,v-bind,v-show,v-model 等等一系列方便快捷的指令 今天一起来了解一下vue里提供的自定义指令 Vue3指令的钩子函数 created 元素初始化的时候beforeMount 指令绑定到元素后调用 只调用一次mounted 元素插入父级dom…...
数据资产新范式,URP城市焕新平台东博会首发!
城市数据资产蕴藏着巨大的宝藏。今年1月,国家数据局印发《“数据要素”三年行动计划(2024—2026年)》,将“数据要素智慧城市”上升为“数据要素”计划的重要部分,加速释放城市数据资产价值。 高质量发展以数据要素驱动…...
儿童乐园软件下载安装 佳易王游乐场会员扣次管理系统操作教程
一、前言 儿童乐园软件下载安装 佳易王游乐场会员扣次管理系统操作教程 软件为绿色免安装版,已经内置数据库,不需再安装数据库文件,软件解压即可。 二、软件程序教程 1、软件可同时管理多个项目,项目设置方法如图,点…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
