Spring框架源码分析一

news2024/10/7 2:29:36

如何看源码(方法论)

  • 不要忽略源码中的注释

  • 使用翻译工具

  • 先梳理脉络,然后梳理细节即总分总,先总体过一遍,再看细节,再做一个总结

  • 大胆猜测(8分靠猜),小心验证,再调整思路

  • 坚持、坚持、坚持

  • 遇到不会的,先迈过去,先不处理

坦白说看源码就是为了工作或为了技能的提升,被迫做这样的事情;

一定要掌握技巧,刚开始会很痛苦,在收获成就感之后才会慢慢产生兴趣,有了兴趣,再坚持就容易很多。

Spring IOC和AOP

原来想使用某一个对象,必须自己去new,现在spring帮我们管理和创建这些对象,这些过程不需要我们去做了,如果要用直接从容器中拿可以了。

spring创建对象大致思路(粗粒度)

看源码之前先理思路,先从spring xml方式创建对象开始,

id class是指我们要创建的那些bean对象,

第一步先读取配置文件,把它加载到当前应用程序里面去,

第二步通过解析知道有什么样的属性值、属性名称,

把这些信息都解析完成之后,再创建实例即一个具体的对象,创建出来之后,就可以直接使用了,使用完之后,还有一个销毁的过程。

再从粗粒度中拆分出一些具体细节的点

Spring里面有IOC (控制反转) 和AOP,容器是用来存放bean对象的,那用什么样的数据结构来存?

可以用list、set、map,这三个最大的区别是存取值的方式不一样,

在整个容器里面会存放n多对象,在后面使用的时候,根据一些描述来取出具体的一个值,这个时候就意味着我要根据名字来取出具体value值,所以它最终存储的是k-v格式的数据,这时候只能用map结构存储。

当把这些前置知识都搞明白了,再来细化具体的过程,spring到底是如何进行架构设计的?

当new一个对象的时候或通过其他方式创建对象的时候,才能存储到IOC容器中,存完之后,后面才能取。

这里面会涉及到创建对象的方式,创建对象有几种方式:

  • 第一个是new

  • 第二个是反射

在这些基础之上可以利用一些设计模式,比如用工厂模式创建对象,但不管什么样的方式,最终是要创建对象的。

创建对象的时候要思考另外一个非常核心的点,你创建出来的对象是一个通用的?还是每次都是新的?

spring bean默认的scope作用域是单例的,当然可以指定protype,但是一般情况下没有做特殊指定的话默认就是单例的,也可以指定request或session。

因为每次都new一个新的就不是一个单例对象了,所以spring就放弃了new的方式创建对象。

那反射怎么写代码

1、第一步先获取一个Class clazz=class.forName();

参数是类名.class或对象名.getClass

2、生成具体的对象

Constructor ctor= clazz.getDeclareConstructor()获取构造器,当有了构造器之后,Object obj=ctor.newInstance就可以返回一个具体对象了。

bean的描述信息或定义信息(名字、哪个class、有哪些property) 都会进行相关的存储,当这些东西都定义好之后,容器就可以启动了:

第一步先进行相关的加载,加载完之后进行一个相关的解析工作。

把它对应的一些描述信息(bean的定义信息)转换成一个具体的对象,因此定义一个接口叫BeanDefinition来表示bean的定义信息。

原来的时候是在注解或xml文件里面配置,现在加载到当前容器里面去了。

springboot用的yaml或property配置文件,属于另外一个类型的配置文件了,哪怕是json里面也可以定义bean的描述信息,只要对json进行解析就可以了。

不同的文件需要进行不同的解析工作,中间要进行一个抽象层,抽象存在的意义是定义一些相关的规范或者定义一些相关的方法,由对应的方法来完成具体的解析工作 ,那么再由具体的实现子类去进行相关的一个实现就可以了。

解析xml文件,定义一个xml的读取类;解析json文件,定义一个json的读取类;新的配置文件,依然可以定义新的实现类进行相关的读取和解析工作,这个读取的抽象类就是BeanDefinitionReader,专门用来完成读取的工作。

当还需要一些其他的配置文件的时候,只需要创建具体的子类实现这个接口进行解析就可以了,解析完之后,有一个统一的出口都放到BeanDefinition中去,就相当于提前做了一个抽象,这层抽象来完成具体对应的一个功能,此时已经有了bean的定义信息了,下一步就要把当前这个bean进行一些实例化工作,

通过这种方式可以获取到一个具体的bean对象,当我在获取bean对象的时候,是直接从当前容器里面拿的,拿的前提是一定要有。

想获取都一个完整的对象,一般包含2部分操作,第一部分叫实例化,还有一个叫初始化,实例化在堆中开辟一块空间,属性都是默认值;初始化是给属性赋值,赋值完之后已经变成一个完整对象了,就可以直接拿过来使用了。给属性赋值的操作也分为2个操作,第一个叫填充属性,另外一个叫执行初始化方法。

python中的__new__表示创建了对象,但是属性没有赋任何值,__init 完成了赋值操作;

java中没有明确的这样的一个划分,所以它包含两部分,第一个是填充属性,就表示说调用set方法给属性填充值,当把具体的一个属性填充完成之后,可以调用一个方法叫init-method,执行这个属性指定的方法里面具体实现的一个逻辑。

bean对象里面这样使用init-method和destroy-method。

实例化后下面的某个环节应该包含初始化操作,当对应的初始化完成了之后,获取到一个最终的完整对象,有了完整对象之后就可以进行一个相关的使用了。

spirng是一个框架,除了框架之外还有一点叫生态,springboot或springcloud都是在spirng基础之上演变过来的 或扩展出来的,所以在设计spring源码的时候要注意一件事情,要考虑一个非常主要的点叫扩展性,只有扩展性设计好了,后面才能随意发挥。spring框架在在整个生态里面代表的是基石或叫底层支撑。

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

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

相关文章

ChatGPT真神奇,但是也真焦虑

ChatGPT火爆ChatGPT的火爆程度不用说也知道。就目前来说,已经开始冲击各行业了,比如客服、智能助手、语言学习、自然语言处理等等等。。ChatGPT冲击冲击最高的可能就是中间这个段位的了。高段位无法取代,但是低段位,通过使用ChatG…

Linux - 第7节 - 进程间通信

1.进程间通信介绍 进程间通信目的: 数据传输:一个进程需要将它的数据发送给另一个进程 。​​​​​​​ 资源共享:多个进程之间共享同样的资源。 ​​​​​​​ 通知事件:一个进程需要向另一个或一组进程发送消息,通…

数据结构-用栈实现队列

前言: 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty): 实现 MyQueue 类: void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int…

双通道5.2GSPS(或单通道10.4GSPS)射频采样FMC+模块

概述 FMC140是一款具有缓冲模拟输入的低功耗、12位、双通道(5.2GSPS/通道)、单通道10.4GSPS、射频采样ADC模块,该板卡为FMC标准,符合VITA57.1规范,该模块可以作为一个理想的IO单元耦合至FPGA前端,8通道的JE…

socket编程-UDP各函数及其用法

socket编程-UDP socket主要类型 流套接字(SOCK_STREAM) 流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输…

电商API分享:获得淘宝商品评论、商品评论问答列表 分页显示 代码展示

item_review-获得淘宝商品评论item_question_answer-淘宝评论问答列表接口请求示例<?php// 请求示例 url 默认请求参数已经URL编码处理 // 本示例代码未加密secret参数明文传输&#xff0c;若要加密请参考&#xff1a;https://open.qq1635608656.cn/help/demo/sdk/demo-sig…

关于IDEA系列行号左侧空白处太宽的缩短

IntelliJ IDEA行号左侧空白处太宽&#xff0c;缩短的方法修改之前打开设置File–Settings–Editor–General–Gutter Icons&#xff08;可以在Settings左上角搜索框直接搜Gutter Icons&#xff09;将对号去掉就好了 &#xff0c;但是这些符号今后不会显示 &#xff0c;最重要的…

【数据结构】单链表中,如何实现 将链表中所有结点的链接方向“原地”逆转

一.实现一个单链表&#xff08;无头单向不循环&#xff09; 我们首先实现一个无头单向不循环单链表。 写出基本的增删查改功能&#xff0c;以及其它的一些功能&#xff08;可忽略&#xff09;。 #include<stdio.h> #include<assert.h> #include<stdlib.h>…

ros使用详解

文章目录ros概述ros使用winbox登录ros关机重启ros修改路由器名ros恢复出厂设置ros修改管理员账号密码及限制登录IPros备份还原ros使用pppor拨号ros的nat&#xff0c;也叫伪装ros静态ARP绑定ros端口映射ros配置静态路由ros概述 软路由是指利用台式机或服务器的供应商配合一定软…

mos管驱动与米勒平台介绍、消除

mos驱动设计 1.选择适当的驱动芯片 为了控制MOSFET&#xff0c;需要使用专门的驱动芯片。选择合适的芯片需要考虑MOSFET的电压和电流需求。常见的驱动芯片包括IR2110、IR2184、MIC4424等。 2.设计电路 在驱动电路中&#xff0c;需要加入一些电路元件来保证MOSFET的顺畅工作…

爱国者一体机电脑蓝屏怎么U盘重装系统教学?

爱国者一体机电脑蓝屏怎么U盘重装系统教学&#xff1f;有用户使用的爱国者一体机电脑开机了之后突然变成了蓝屏的了。而且无法继续使用了&#xff0c;那么遇到这样的蓝屏问题怎么去进行系统的重装呢&#xff1f;一起来看看以下的U盘重装系统教学吧。 准备工作&#xff1a; 1、U…

es6动态模块import()

目录 一、语法说明 二、适用场合 三、注意点 四、示例代码 五、效果 一、语法说明 import命令会被 JavaScript 引擎静态分析&#xff0c;先于模块内的其他语句执行&#xff08;import命令叫做“连接” binding 其实更合适&#xff09;。 // 报错 if (x 2) {import MyMod…

网络安全工程师在面试安全岗位时,哪些内容是加分项?

金三银四已经来了&#xff0c;很多小伙伴都在困惑&#xff0c;面试网络安全工程师的时候&#xff0c;有哪些技能是加分项呢&#xff1f;接下来&#xff0c;我简单说说&#xff01; 去年我在微博上贴了一些在面试安全工作时会加分的内容&#xff0c;如下&#xff1a; 1. wooyu…

MySQL、HBase、ElasticSearch三者对比

1、概念介绍 MySQL&#xff1a;关系型数据库&#xff0c;主要面向OLTP&#xff0c;支持事务&#xff0c;支持二级索引&#xff0c;支持sql&#xff0c;支持主从、Group Replication架构模型&#xff08;本文全部以Innodb为例&#xff0c;不涉及别的存储引擎&#xff09;。 HBas…

【AI JUST AI】自然语言交互式学习,ChatGPT成了我的最佳博客写作助手

【AI JUST AI】自然语言交互式学习&#xff0c;ChatGPT成了我的最佳博客写作助手什么是自然语言交互式学习&#xff1f;ChatGPT是如何成为我的最佳博客写作助手的&#xff1f;**把与Chat GPT的每一次对话都当作一种类型的非系统学习**有问必答&#xff0c;随时交互总结后记——…

【Python】案例介绍Pytest进行压力测试

在现代Web应用程序中&#xff0c;性能是至关重要的。为了确保应用程序能够在高负载下正常运行&#xff0c;我们需要进行性能测试。 今天&#xff0c;应小伙伴的提问&#xff0c; 田辛老师来写一个Pytest进行压力测试的简单案例。 这个案例的测试网站我们就隐藏了&#xff0c;不…

Windows 10 - Python 消息队列 RabbitMQ 学习总结 1

目录消息队列的基本知识概述什么是消息队列&#xff1f;为何要使用消息队列的原因&#xff1f;理解消息队列服务器和 Web 服务器的关系题外&#xff1a;关于服务端和客户端的企业级理解了解 Web 服务器了解 Web 框架和 Web 服务的区别对于框架和服务器B/S架构消息队列的个人理解…

PMP项目管理项目风险管理

目录1 项目风险管理概述2 规划风险管理3 识别风险4 实施定性风险分析5 实施定量风险分析6 规划风险应对7 实施风险应对8 监督风险1 项目风险管理概述 项目风险管理的目标在于提高正面风险的概率和&#xff08;或&#xff09;影响&#xff0c;降低负面风险的概率和&#xff08;…

STM32CubeIDE 快速开发入门指南

描述 STM32CubeIDE是一体式多操作系统开发工具&#xff0c;是STM32Cube软件生态系统的一部分。 STM32CubeIDE是一种高级C/C开发平台&#xff0c;具有STM32微控制器和微处理器的外设配置、代码生成、代码编译和调试功能。它基于Eclipse/CDT™框架和用于开发的GCC工具链&#xf…

CentOS7部署Doris V1.2.2

一、环境准备 服务器信息 IP配置部署内容192.168.43.1508核8GFE&#xff0c;BE192.168.43.1514核8GBE192.168.43.1524核8GBE 安装前置条件 服务器配置免密登录 3台服务器配置免密登录&#xff0c;可参考CentOS7 设置SSH免密钥登陆 安装JDK 安装JDK 修改CentOS系统默认参…