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

探究Spring的单例设计模式--单例Bean

Spring的单例设计模式

在Spring框架中,单例设计模式是一种常见且重要的设计模式,主要用于确保在应用程序的生命周期中仅创建一个特定的Bean实例

一、什么是单例设计模式?

单例设计模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。这种模式的核心在于控制实例的创建,避免了因为多次创建对象导致的资源浪费。单例模式通常用于以下场景:

  1. 节约资源:在需要大量创建相同对象时,使用单例可以显著减少内存消耗。

  2. 全局访问:单例模式提供了一个全局访问点,使得在任何地方都能轻松获取到该实例,避免了需要通过参数传递对象的复杂性。

  3. 协调操作:在某些情况下,多个对象需要共享状态或资源,单例模式能够确保所有对象都访问到相同的数据。

在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类中进行。具体的创建流程如下:

  1. Bean定义的注册:首先,在Spring容器启动时,所有的Bean定义(包括其元数据)会被注册到DefaultListableBeanFactory中。

  2. Bean的实例化:当一个Bean被请求时,Spring会检查是否已经存在该Bean的实例。对于单例Bean,Spring在第一次请求时会创建实例,并将其存储在缓存中。

2.源码解析

下面是Spring源码中与单例Bean管理相关的几个重要部分:

3.单例Bean的生命周期管理

除了实例化,Spring还负责单例Bean的生命周期管理,包括:

初始化:Bean被实例化后,可以执行初始化方法,例如通过@PostConstruct注解或实现InitializingBean接口。

销毁:在容器关闭时,Spring会调用单例Bean的销毁方法,例如通过@PreDestroy注解或实现DisposableBean接口。

  1. 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注册到单例缓存中。
  2. 单例缓存:Spring使用singletonObjects集合来缓存单例Bean实例,具体在DefaultSingletonBeanRegistry中定义:

    protected final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    
    1. 当一个单例Bean被创建后,Spring会将其实例存储在这个singletonObjects映射中,以便后续请求时直接返回。
  3. 线程安全:Spring确保单例Bean在多线程环境中的安全性。对于单例Bean的创建,通常会在关键部分添加同步机制,以防止多个线程同时创建实例。例如,在创建单例Bean时,Spring会使用synchronized关键字来保证线程安全。

四、总结

Spring的单例设计模式通过确保Bean在整个应用程序中只有一个实例,提供了高效的资源管理和简化的访问方式。理解单例Bean的实现原理及其在多线程环境中的安全性,对于开发高效的Spring应用至关重要。

相关文章:

探究Spring的单例设计模式--单例Bean

Spring的单例设计模式 在Spring框架中&#xff0c;单例设计模式是一种常见且重要的设计模式&#xff0c;主要用于确保在应用程序的生命周期中仅创建一个特定的Bean实例 一、什么是单例设计模式&#xff1f; 单例设计模式是一种创建型设计模式&#xff0c;确保一个类只有一个…...

js基础速成-Set、Map

集合&#xff08;Set&#xff09; 集合是元素的集合&#xff0c;只能包含唯一元素 创建一个空集合 const companies new Set() console.log(companies)Set(0) {}从数组创建集合 const languages [英语,芬兰语,英语,法语,西班牙语,英语,法语, ]const setOfLanguages new …...

手机软件何时统一——桥接模式

文章目录 手机软件何时统一——桥接模式凭什么你的游戏我不能玩紧耦合的程序演化合成&#xff0f;聚合复用原则松耦合的程序桥接模式桥接模式基本代码 手机软件何时统一——桥接模式 凭什么你的游戏我不能玩 时间&#xff1a;5月31日20点  地点&#xff1a;大鸟房间  人物…...

【Nacos 架构 原理】服务发现模块之Nacos注册中心服务数据模型

文章目录 服务&#xff08;Service&#xff09;和服务实例&#xff08;Instance&#xff09;定义服务服务元数据定义实例实例元数据持久化属性 集群定义集群 生命周期服务的生命周期实例的生命周期集群的生命周期元数据的生命周期 服务&#xff08;Service&#xff09;和服务实…...

基于微信小程序爱心领养小程序设计与实现(源码+参考文档+定制开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…...

【数据库】 MongoDB 用户分配新的角色和权限

在 MongoDB 中&#xff0c;可以通过简单的命令为用户分配新的角色和权限。这对于调整用户的访问能力和管理数据库安全至关重要。以下是如何为用户分配新的角色和权限的详细步骤。 1. 使用 MongoDB Shell 分配角色 1.1 修改用户角色 要为现有用户分配新的角色&#xff0c;可以…...

加速 Python for 循环

在 Python 编程中&#xff0c;for 循环是开发者常用的工具之一&#xff0c;但它的执行速度经常让人感到不满。幸运的是&#xff0c;有许多方法可以显著提高 for 循环的效率。 本文将介绍几种简单而高效的优化技巧&#xff0c;帮助你加速Python for 循环&#xff0c;速度提升从…...

计算机毕业设计 基于Python国潮男装微博评论数据分析系统的设计与实现 Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

React 表单与事件

React 表单与事件 React 是一个用于构建用户界面的 JavaScript 库&#xff0c;它通过组件化的方式来提高开发效率和代码的可维护性。在 React 应用中&#xff0c;表单和事件处理是核心功能之一&#xff0c;它们允许用户与应用程序进行交互。本文将深入探讨 React 中的表单处理…...

Appium独立测试自动化初始化脚本

1、查看环境初始化参数 确保appium已经开起来了&#xff0c;设置ip ,并点击启动 打开夜神模拟器&#xff0c;点击工具--设置 最下面的版本说明&#xff0c;双击进去 版本号这里再去单击。 直到进入到开发者模式。 可能我们不是开发者模式打开的状态&#xff0c;所以软件访问模…...

Nginx反向代理配置支持websocket

一、官方文档 WebSocket proxying 为了将客户端和服务器之间的连接从HTTP/1.1转换为WebSocket&#xff0c;使用了HTTP/1.1中可用的协议切换机制&#xff08;RFC 2616: Hypertext Transfer Protocol – HTTP/1.1&#xff09;。 然而&#xff0c;这里有一个微妙之处:由于“升级”…...

C# 游戏引擎中的协程

前言 书接上回&#xff0c;我谈到了Unity中的协程的重要性&#xff0c;虽然协程不是游戏开发“必要的”&#xff0c;但是它可以在很多地方发挥优势。 为了在Godot找回熟悉的Unity协程开发手感&#xff0c;不得不自己做一个协程系统&#xff0c;幸运的是&#xff0c;有了Unity的…...

如何封装微信小程序中的图片上传功能

文章目录 前言一、需求分析与设计思路二、上传图片功能封装三、页面调用示例四、功能改进与扩展4.1 压缩图片4.2 上传进度4.3 重试机制 五、总结 前言 在微信小程序开发中&#xff0c;图片上传功能是一个十分常见的需求&#xff0c;不管是社交分享、商城中的商品图片上传&…...

被问界/理想赶超!奔驰CEO再度“出马”,寻找中国外援

来自中国车企的全方位、持续施压&#xff0c;让大部分外资车企开始寻求更多的本地化合作来实现技术升级。传统豪华品牌也同样如此。 本周&#xff0c;知情人士透露&#xff0c;梅赛德斯奔驰首席执行官Ola Kllenius计划再次访问中国&#xff0c;目的是进一步寻求和扩大与本地技术…...

魔改xjar支持springboot3,

jar包加密方案xjar, 不支持springboot3。这个发个魔改文章希望大家支持 最近公司需要将项目部署在第三方服务器&#xff0c;于是就有了jar包加密的需求&#xff0c;了解了下目前加密方案现况如下: 混淆方案&#xff0c;就是在代码中添加大量伪代码&#xff0c;以便隐藏业务代…...

python json文件读写

在Python中处理JSON文件是一个常见的任务。JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。Python提供了内置的json模块来帮助我们读取和写入JSON格式的数据。 如何读…...

Android常用C++特性之std::find_if

声明&#xff1a;本文内容生成自ChatGPT&#xff0c;目的是为方便大家了解学习作为引用到作者的其他文章中。 std::find_if 是 C 标准库中的一个算法&#xff0c;用于在给定范围内查找第一个满足特定条件的元素。它接受一个范围&#xff08;由迭代器指定&#xff09;和一个谓词…...

19 vue3之自定义指令Directive按钮鉴权

directive-自定义指令(属于破坏性更新) Vue中有v-if,v-for,v-bind,v-show,v-model 等等一系列方便快捷的指令 今天一起来了解一下vue里提供的自定义指令 Vue3指令的钩子函数 created 元素初始化的时候beforeMount 指令绑定到元素后调用 只调用一次mounted 元素插入父级dom…...

数据资产新范式,URP城市焕新平台东博会首发!

城市数据资产蕴藏着巨大的宝藏。今年1月&#xff0c;国家数据局印发《“数据要素”三年行动计划&#xff08;2024—2026年&#xff09;》&#xff0c;将“数据要素智慧城市”上升为“数据要素”计划的重要部分&#xff0c;加速释放城市数据资产价值。 高质量发展以数据要素驱动…...

儿童乐园软件下载安装 佳易王游乐场会员扣次管理系统操作教程

一、前言 儿童乐园软件下载安装 佳易王游乐场会员扣次管理系统操作教程 软件为绿色免安装版&#xff0c;已经内置数据库&#xff0c;不需再安装数据库文件&#xff0c;软件解压即可。 二、软件程序教程 1、软件可同时管理多个项目&#xff0c;项目设置方法如图&#xff0c;点…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...