探秘Spring的设计精髓,深入解析架构原理
序员与平庸的程序员之间的区别,是在于认为自己的代码重要还是数据结构更加重要。平庸的程序员眼里只有代码,优秀的程序员则关注数据结构及之前的关系。”
1、spring的设计理念
spring提供了一个轻量级的开发框架,抽象了实际开发中的很多共性问题;在javaee的开发中,支持pojo和使用javabean的开发方式,使应用面向接口开发、充分支持OO;
通过spring的ioc容器,将复杂的对象耦合关系变成了一个文本化、外部化的工作,通过一个或几个xml文件来方便的对应用对象的耦合关系进行维护、修改和浏览,极大地简化了应用开发;
通过ioc容器的依赖反转,将依赖关系从java对象中解放出来,交给了ioc容器完成,对象之间的关系进行了解耦,对象——对象之间的关系转化成了对象——IOC容器——对象的关系;
IOC容器和AOP模块是spring最为基础的底层抽象,IOC来管理bean对象,aop以动态和非侵入的方式增强服务功能。
2、spring的整体架构
springioc、spring aop、springmvc、springjdbc/orm、spring事务处理、spring的远端调用、spring应用;其中aop以纵向切面的方式贯穿在整个架构中;
Spring 中两个数据结构最核心:① BeanDefinition,用于表示 Bean 的定义;② BeanFactory,用于表示整个 IoC 容器。
3、spring framework的核心:IOC容器的实现
ioc容器概述
面向对象系统:对象封装了数据和对数据的处理,对象的依赖关系主要体现在对数据和方法的依赖上。这种依赖关系可以通过把对象的依赖注入交给框架或者IOC容器来完成
依赖注入:依赖对象获得被反转了,由自身主动地获取反转到交给ioc容器来注入、获取。新建对象、对象的引用赋值等操作交由容器来统一完成。从而将散落在不同代码中的功能相同的部分集中成了容器的一部分,成了面向对象基础设施的一部分。
对面向对象系统中的对象分为2类:数据对象、处理数据的对象。后者不经常变化,很少涉及数据和状态共享的问题,是系统中基础的部分。同时这些对象间依赖关系也很稳定,这些特性非常适合由ioc容器来进行管理
IOC容器的设计与实现:
BeanFactory和ApplicationContext:
我们通常说的ioc容器实际上指的是一些功能各异的容器产品,各有特点
beanfactory:容器的基本功能;applicationcontext:应用上下文,作为容器的高级形态而存在,增加了很多面向框架的特性和适配。
beandefinition:抽象了对bean的定义,管理各种对象,是依赖翻转模式中管理的对象依赖关系的数据抽象,是容器发挥作用的主要数据类型。计算机中,所有的功能都是建立在通过数据对现实进行抽象的基础上的。
IOC容器的接口设计关系:
1、从接口BeanFactory---HierarchicalBeanFactory---ConfigurableBeanFactory,是一条主要的BeanFactory设计路径。
2、第二条接口设计主线是以ApplicationContext应用上下文接口为核心的接口设计,从BeanFactory---ListableBeanFactory---ApplicationContext---WebApplicationContext(ConfigurableApplicationContext)。
3、具体的IoC容器都是在以上的接口体系下实现的,比如DefaultListableBeanFactory,实现了ConfigurableBeanFactory,从而成为一个简单IoC容器的实现。其他的如XmlBeanFactory,都是在DefaultListableBeanFactory的基础上做扩展,ApplicationContext也是如此。
4、BeanFactory是IoC容器最基本的接口,提供的是最基本的IoC容器的功能,比如getBean、containsBean等,其他高级IoC容器接口再在此基础功能上进行扩展。
5、BeanFactory是一个对象工厂,管理Spring中所有的Bean,而FactoryBean是一个特殊的Bean。
IOC容器的创建步骤:
(1)创建IoC配置文件的抽象资源,包含了BeanDefinition的定义信息;
(2)创建一个BeanFactory;
(3)创建一个载入BeanDefinition的读取器;
(4)从定义好的资源位置读入配置信息。
核心属性(Spring 循环依赖):
Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256):Bean 名称到单例 Bean 的映射,用于存放完全初始化好的 Bean。可以理解成,这就是所谓的容器。这是一级缓存。
Map<String, Object> earlySingletonObjects = new HashMap<>(16):Bean “未成熟”单例 Bean 的映射。该 Bean 对象只是被创建出来,但是还没有注入依赖。在容器解决循环依赖时,用于存储中间状态。这是二级缓存。
Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16):Bean 名称到 Bean 的 ObjectFactory 对象的映射,存放 Bean 工厂对象。在容器解决循环依赖时,用于存储中间状态。这是三级缓存。
Bean 的获取过程就类似计算机缓存的作用过程:先从一级获取,失败再从二级、三级里面获取。org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean) 方法
实际中最长使用的是ApplicationContext这个高级形态的IOC容器。他除了具备基本的beanfactory的功能,还集成了很多附加功能:
支持信息源,可以实现国际化。(实现MessageSource接口)
访问资源。(实现ResourcePatternResolver接口,这个后面要讲)
支持应用事件。(实现ApplicationEventPublisher接口)
在ApplicationContext中提供的附加服务
IOC容器初始化:
refresh()方法标志着ioc容器的正式启动。具体包括beandefinition的resources定位、载入和注册三个过程:
IOC容器的初始化分为三个过程实现:
第一个过程是Resource资源定位。这个Resouce指的是BeanDefinition的资源定位。这个过程就是容器找数据的过程,就像水桶装水需要先找到水一样。
第二个过程是BeanDefinition的载入过程。这个载入过程是把用户定义好的Bean表示成Ioc容器内部的数据结构,而这个容器内部的数据结构就是BeanDefition。
第三个过程是向IOC容器注册这些BeanDefinition的过程,这个过程就是将前面的BeanDefition保存到HashMap中的过程。
Spring容器创建之后,会调用它的refresh方法,refresh的时候会做很多事情:比如完成配置类的解析、各种BeanFactoryPostProcessor和BeanPostProcessor的注册、国际化配置的初始化、web内置容器的构造等等。

相关文章:
探秘Spring的设计精髓,深入解析架构原理
序员与平庸的程序员之间的区别,是在于认为自己的代码重要还是数据结构更加重要。平庸的程序员眼里只有代码,优秀的程序员则关注数据结构及之前的关系。” 1、spring的设计理念 spring提供了一个轻量级的开发框架,抽象了实际开发中的很多共…...
Python Wordcloud报错:Only supported for TrueType fonts,多种解决方案
Python Wordcloud报错:Only supported for TrueType fonts,多种解决方案。 报错内容如下: 2023-10-26T09:35:41.190459839Z Traceback (most recent call last): 2023-10-26T09:35:41.190502589Z File “lib/task/compute.py”, line 621, i…...
为虚拟网络提供敏捷负载均衡:Everoute LB 特性解读
为了保证应用系统的可用性,同时避免并发访问导致后端服务器出现性能瓶颈,不少用户都通过负载均衡技术优化流量分发。随着虚拟化平台下用户业务规模的持续扩大,虚拟化网络的数据访问量也不断增加,而传统负载均衡通常通过硬件负载均…...
Jmeter 接口测试,参数值为列表,如何参数化?
最近在我的教学过程中,我的一个学生问了我一个问题,他们公司的一个接口参数值是列表,列表中值的数量有多有少,问我在 jmeter 中如何让这个参数的值进行参数化? 看到这种问题,你的第一反应是什么?…...
DeepinV20实现使用CapsLock键切换输入法
概览 起因参考资料解决问题1. 删除CapsLock键映射关系2. 新建CapsLock键映射关系3. 建立配置文件4. **注销用户或者重启电脑**5. 修改切换输入法快捷键6. 测试输入 起因 看同事的MacBook可以使用CapsLock键切换输入法,而我作为Shift党CapsLock键几乎不使用…...
基于springboot实现校友社交平台管理系统项目【项目源码+论文说明】计算机毕业设计
基于springboot实现校友社交平台管理系统演示 摘要 校友社交系统提供给用户一个校友社交信息管理的网站,最新的校友社交信息让用户及时了解校友社交动向,完成校友社交的同时,还能通过论坛中心进行互动更方便。本系统采用了B/S体系的结构,使用了java技…...
WordPress主题模板 大前端D8 5.1版本完整开源版源码简洁大气多功能配置
源码测评:该模板官方已更新至5.2,但是这个5.1也是非常好用的,经测试所有页面均完好,推荐下载使用。 模板简介: 大前端D8 主题是一款非常牛逼的WordPress博客主题,响应式,功能齐全,支持手机,电脑,平板,非常适合做博客站…...
如何在Postman中使用静态HTTP
首先,打开 Postman 软件。在 Postman 的菜单栏中,点击 “Preferences”(偏好设置)。 亲身经验:我自己尝试了这个方法,发现它非常适用于需要使用HTTP的场景。 数据和引证:根据 Postman 官方文档…...
vscode 提升Vue开发效率的必备插件与工具
1,Vetur:提供了Vue语法高亮、智能提示、代码片段、错误检查和格式化等功能,是Vue开发中必不可少的插件。 2,ESLint:用于检查和修复JavaScript和Vue代码中的语法错误和潜在问题,提高代码质量。 3ÿ…...
mysql/java/springboot/javaweb请假系统,分为学生/辅导员/超级管理员
源码下载地址 支持:远程部署/安装/调试、讲解、二次开发/修改/定制 系统分为 学生/辅导员/超级管理员 学生 辅导员 超级管理员...
Android11系统桌面隐藏指定APP图标
做项目时有时会遇到这样的需求,客户要求隐藏Launcher3桌面的某个app图标,但是又不能删除去掉这个app,具体修改如下: diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTa…...
WEB使用百度地图展示某地地址
第一步 进入百度地图开发平台 百度地图开放平台 | 百度地图API SDK | 地图开发 第二步注册 获取AK秘钥,点击【创建应用】进入AK申请页面,填写应用名称,务必选择AK类型为“浏览器端”,JS API只支持浏览器端AK进行请求与访问 下面…...
22年上半年下午题
第一大题题目 第一大题解答 第一小问 看加工交互和说明来得出实体的名字。如果不太确定,可以多去看几条数据流来确认答案。仔细一点,这分稳啦。 第二小问 需要对应加工结合说明得出数据存储的名称。 一般可以在后面加上表字或者加上信息表。自拟&…...
大文件分片上传-续传-秒传(详解)
前言 前面记录过使用库实现的大文件的分片上传 基于WebUploader实现大文件分片上传 基于vue-simple-uploader 实现大文件分片上传 前面记录过基于库实现的大文件的分片上传,那如果不使用库, 文件分片是怎么实现的,该怎么做到呢?…...
CE-LVD证书跟CE-EMC证书有什么区别?
CE-LVD证书跟CE-EMC证书有什么区别? CE-LVD证书跟CE-EMC证书有什么区别? 近日,TEMU平台电器需提交CE-LVD证书,不再接受EMC证书---玩具产品需提交满足玩具法规的CE证书,法规总是多变的,卖家也是很苦恼&…...
使用Mapster实现双向映射,解放搬砖体力活
经常会有对象属性互相赋值的操作,但是频繁的写实在是搬运工一样,比较难受比如下面两个类 public class AgencyBdm {public new int Id { set; get; }public string AgencyId { set; get; }public string AgencyName { set; get; }public string Region {…...
一种基于屏幕分辨率的RTSP主子码流切换的多路视频监控的播放方案
技术背景: 用户场景下,存在多个监控场所的100路监控摄像头,例如:大华、海康、宇视、杭州宇泛的枪机、球机、半球、NVR、DVR等不同类型的监控设备,通过视频监控平台进行设备的管理,通过RTSP拉流的方案管理监…...
SpringBoot日志+SpringMVC+UUID重命名文件+Idea热部署
目录 【SpringBoot日志】 什么是日志,日志的作用 关于日志的基本信息,又有哪些呢? 关于日志的级别 Springboot内置SLF4J【门面模式】 和 logback【日志框架】 在配置文件中可以设置日志级别【以.yml为例】 SpringBoot 持久化的保存日…...
向日葵远程控制中的键盘异常问题
本文记录的是ubuntu 20.04 上, 向日葵的最高版本目前只有V 11.0.1.44968(2022.02) 我的被控制和 控制端都是上述环境; 起因,由于我昨天在控制端按下了 win/ 或者是其他的组合键 (具体哪个键盘确实没有注…...
【iOS免越狱】利用IOS自动化web-driver-agent_appium-实现自动点击+滑动屏幕
1.目标 在做饭、锻炼等无法腾出双手的场景中,想刷刷抖音 刷抖音的时候有太多的广告 如何解决痛点 抖音自动播放下一个视频 iOS系统高版本无法 越狱 安装插件 2.操作环境 MAC一台,安装 Xcode iPhone一台,16 系统以上最佳 3.流程 下载最…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
