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

探秘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容器的接口设计关系:

2ab20ac8d14006ad20db066da507a224.jpeg

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)从定义好的资源位置读入配置信息。

c8eec0cca540ce0d0e1e32df4173d743.jpeg

核心属性(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内置容器的构造等等。

6f9d2a05c64856b44843fdab3142cea3.jpeg

相关文章:

探秘Spring的设计精髓,深入解析架构原理

序员与平庸的程序员之间的区别&#xff0c;是在于认为自己的代码重要还是数据结构更加重要。平庸的程序员眼里只有代码&#xff0c;优秀的程序员则关注数据结构及之前的关系。” 1、spring的设计理念 spring提供了一个轻量级的开发框架&#xff0c;抽象了实际开发中的很多共…...

Python Wordcloud报错:Only supported for TrueType fonts,多种解决方案

Python Wordcloud报错&#xff1a;Only supported for TrueType fonts&#xff0c;多种解决方案。 报错内容如下&#xff1a; 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 特性解读

为了保证应用系统的可用性&#xff0c;同时避免并发访问导致后端服务器出现性能瓶颈&#xff0c;不少用户都通过负载均衡技术优化流量分发。随着虚拟化平台下用户业务规模的持续扩大&#xff0c;虚拟化网络的数据访问量也不断增加&#xff0c;而传统负载均衡通常通过硬件负载均…...

Jmeter 接口测试,参数值为列表,如何参数化?

最近在我的教学过程中&#xff0c;我的一个学生问了我一个问题&#xff0c;他们公司的一个接口参数值是列表&#xff0c;列表中值的数量有多有少&#xff0c;问我在 jmeter 中如何让这个参数的值进行参数化&#xff1f; 看到这种问题&#xff0c;你的第一反应是什么&#xff1f…...

DeepinV20实现使用CapsLock键切换输入法

概览 起因参考资料解决问题1. 删除CapsLock键映射关系2. 新建CapsLock键映射关系3. 建立配置文件4. **注销用户或者重启电脑**5. 修改切换输入法快捷键6. 测试输入 起因 看同事的MacBook可以使用CapsLock键切换输入法&#xff0c;而我作为Shift党CapsLock键几乎不使用&#xf…...

基于springboot实现校友社交平台管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现校友社交平台管理系统演示 摘要 校友社交系统提供给用户一个校友社交信息管理的网站&#xff0c;最新的校友社交信息让用户及时了解校友社交动向,完成校友社交的同时,还能通过论坛中心进行互动更方便。本系统采用了B/S体系的结构&#xff0c;使用了java技…...

WordPress主题模板 大前端D8 5.1版本完整开源版源码简洁大气多功能配置

源码测评&#xff1a;该模板官方已更新至5.2&#xff0c;但是这个5.1也是非常好用的&#xff0c;经测试所有页面均完好&#xff0c;推荐下载使用。 模板简介&#xff1a; 大前端D8 主题是一款非常牛逼的WordPress博客主题,响应式,功能齐全,支持手机,电脑,平板,非常适合做博客站…...

如何在Postman中使用静态HTTP

首先&#xff0c;打开 Postman 软件。在 Postman 的菜单栏中&#xff0c;点击 “Preferences”&#xff08;偏好设置&#xff09;。 亲身经验&#xff1a;我自己尝试了这个方法&#xff0c;发现它非常适用于需要使用HTTP的场景。 数据和引证&#xff1a;根据 Postman 官方文档…...

vscode 提升Vue开发效率的必备插件与工具

1&#xff0c;Vetur&#xff1a;提供了Vue语法高亮、智能提示、代码片段、错误检查和格式化等功能&#xff0c;是Vue开发中必不可少的插件。 2&#xff0c;ESLint&#xff1a;用于检查和修复JavaScript和Vue代码中的语法错误和潜在问题&#xff0c;提高代码质量。 3&#xff…...

mysql/java/springboot/javaweb请假系统,分为学生/辅导员/超级管理员

源码下载地址 支持&#xff1a;远程部署/安装/调试、讲解、二次开发/修改/定制 系统分为 学生/辅导员/超级管理员 学生 辅导员 超级管理员...

Android11系统桌面隐藏指定APP图标

做项目时有时会遇到这样的需求&#xff0c;客户要求隐藏Launcher3桌面的某个app图标&#xff0c;但是又不能删除去掉这个app&#xff0c;具体修改如下&#xff1a; diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTa…...

WEB使用百度地图展示某地地址

第一步 进入百度地图开发平台 百度地图开放平台 | 百度地图API SDK | 地图开发 第二步注册 获取AK秘钥&#xff0c;点击【创建应用】进入AK申请页面&#xff0c;填写应用名称&#xff0c;务必选择AK类型为“浏览器端”&#xff0c;JS API只支持浏览器端AK进行请求与访问 下面…...

22年上半年下午题

第一大题题目 第一大题解答 第一小问 看加工交互和说明来得出实体的名字。如果不太确定&#xff0c;可以多去看几条数据流来确认答案。仔细一点&#xff0c;这分稳啦。 第二小问 需要对应加工结合说明得出数据存储的名称。 一般可以在后面加上表字或者加上信息表。自拟&…...

大文件分片上传-续传-秒传(详解)

前言 前面记录过使用库实现的大文件的分片上传 基于WebUploader实现大文件分片上传 基于vue-simple-uploader 实现大文件分片上传 前面记录过基于库实现的大文件的分片上传&#xff0c;那如果不使用库&#xff0c; 文件分片是怎么实现的&#xff0c;该怎么做到呢&#xff1f;…...

CE-LVD证书跟CE-EMC证书有什么区别?

CE-LVD证书跟CE-EMC证书有什么区别&#xff1f; CE-LVD证书跟CE-EMC证书有什么区别&#xff1f; 近日&#xff0c;TEMU平台电器需提交CE-LVD证书&#xff0c;不再接受EMC证书---玩具产品需提交满足玩具法规的CE证书&#xff0c;法规总是多变的&#xff0c;卖家也是很苦恼&…...

使用Mapster实现双向映射,解放搬砖体力活

经常会有对象属性互相赋值的操作&#xff0c;但是频繁的写实在是搬运工一样&#xff0c;比较难受比如下面两个类 public class AgencyBdm {public new int Id { set; get; }public string AgencyId { set; get; }public string AgencyName { set; get; }public string Region {…...

一种基于屏幕分辨率的RTSP主子码流切换的多路视频监控的播放方案

技术背景&#xff1a; 用户场景下&#xff0c;存在多个监控场所的100路监控摄像头&#xff0c;例如&#xff1a;大华、海康、宇视、杭州宇泛的枪机、球机、半球、NVR、DVR等不同类型的监控设备&#xff0c;通过视频监控平台进行设备的管理&#xff0c;通过RTSP拉流的方案管理监…...

SpringBoot日志+SpringMVC+UUID重命名文件+Idea热部署

目录 【SpringBoot日志】 什么是日志&#xff0c;日志的作用 关于日志的基本信息&#xff0c;又有哪些呢&#xff1f; 关于日志的级别 Springboot内置SLF4J【门面模式】 和 logback【日志框架】 在配置文件中可以设置日志级别【以.yml为例】 SpringBoot 持久化的保存日…...

向日葵远程控制中的键盘异常问题

本文记录的是ubuntu 20.04 上&#xff0c; 向日葵的最高版本目前只有V 11.0.1.44968&#xff08;2022.02&#xff09; 我的被控制和 控制端都是上述环境&#xff1b; 起因&#xff0c;由于我昨天在控制端按下了 win/ 或者是其他的组合键 &#xff08;具体哪个键盘确实没有注…...

【iOS免越狱】利用IOS自动化web-driver-agent_appium-实现自动点击+滑动屏幕

1.目标 在做饭、锻炼等无法腾出双手的场景中&#xff0c;想刷刷抖音 刷抖音的时候有太多的广告 如何解决痛点 抖音自动播放下一个视频 iOS系统高版本无法 越狱 安装插件 2.操作环境 MAC一台&#xff0c;安装 Xcode iPhone一台&#xff0c;16 系统以上最佳 3.流程 下载最…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

YSYX学习记录(八)

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

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...