从SpringBoot启动,阅读源码设计

简介: 服务端开发,绕不开对Spring框架的深度学习,如果单纯站在源码阅读的角度,建议先熟读SpringBoot启动流程,然后再适当扩展其他源码块;
服务启动堪称Spring源码设计的答案;

一、背景说明

初学SpringBoot框架时,第一次启动服务,直呼什么鬼?只需要简单的几步配置,几个核心的注解,就可以快速实现工程的搭建和运行;

虽然从Spring框架迁移到SpringBoot框架,在初期会有很多的不适应,但是更好用的框架会快速得到认可,从而成为主流的技术选型;

对于大多数的框架或者组件来说,如果使用起来越是简便,那么其内部的封装策略就越是复杂;

比如在Spring框架更新到SpringBoot版本时,其用法的简便与内部封装的复杂性已经形成强烈的对比;再到SpringCloud微服务框架时,其封装逻辑复杂到离谱;

对于服务端的开发来说,绕不开对Spring框架的深度学习,如果单纯站在源码阅读的角度,建议先熟读SpringBoot启动流程,然后再适当扩展其他源码块;

二、SpringBoot工程

首先聊一聊阅读源码的基本思路,从一个极简的案例开始,围绕案例中的核心API作为切入点,通过对源码逻辑的断点调试,从而体会其设计的原理;

阅读SpringBoot的源码,可以从服务启动方法作为切入点,然后不断的分析启动过程涉及到的核心API和设计原理,再基于具体的启动日志去分析抽象的加载逻辑;

1.png

在看具体的源码之前,还需要说下分析思路,Spring项目中,要注意每个API所属工程与层级,然后再去分析API之间关系,核心的构造、属性、方法等;

在SpringBoot的启动类中,有两个核心的切入点,一个是类的构造方法,完成一列的初始化动作;一个是启动方法,实现应用上下文的创建和装载;

构造方法

2.png

启动方法

3.png

需要说明的是,由于SpringBoot服务启动过程涉及源码过多,所以上面的源码中只是罗列部分的核心切入点,然后围绕这些关键流程展开,分析一些常见的源码设计;

另外说明一点,以下源码的核心版本:JDK-1.8spring-5.2.4spring-boot-2.2.5,在不同的版本下源码会存在差异;

三、应用上下文

服务启动时,根据应用类型判断创建的上下文,此处启动的是基于servlet的web应用,所以也依赖相应的web服务器,默认为Tomcat;

启动方法的核心在于对应用上下文的创建、准备、刷新,应用上下文是一个十分抽象的描述,可以理解为应用运行的整体环境,其中涉及到资源加载,配置文件装配,运行服务的管理等,后续的源码分析都围绕该API展开;

4.png

ApplicationContext:应用上下文核心接口,在该接口中所有的方法都是只读模式,即只能通过Get方法进行访问;

ConfigurableApplicationContext:上下文配置扩展接口,提供了应用上下文的配置能力,生命周期的维护,以及在关闭之后的相关资源释放;

AbstractApplicationContext:上下文接口抽象实现,核心的API,对应用上下文中的公共能力做了实现;

ConfigurableWebApplicationContext:Web应用上下文配置扩展接口,提供了Web应用的上下文配置能力;

WebServerApplicationContext:Web服务上下文,创建并管理Web应用的服务器,在该流程中嵌入的是Tomcat服务;

根据应用上下文几个核心的API设计,体会Spring源码的设计思路,从顶级的接口开始,不断向下扩展并且新增方法,理解抽象实现类的逻辑,以及服务运行时所依赖的具体API;

四、资源加载

什么是资源,可以是各种类型的文件和配置,字节输入流的转换,也可以是URL资源定位,Spring框架在运行的过程中,需要依赖Resource接口实现对底层资源的访问;

5.png

Resource:资源描述的顶级接口,提供了一系列的方法,继承InputStreamSource接口,支持将资源转换为流的形式操作;

AbstractResource:资源访问的抽象实现类,这里的设计原理与AbstractApplicationContext类似,提供资源访问方法的基础实现;

ResourceLoader:资源加载的封装接口,应用下文需要依赖该接口实现资源的获取与访问;

针对不同应用场景需求,Resource接口的实现类有如下几个:FileSystemResource文件系统资源,ClassPathResource类路径下资源,InputStreamResource输入流资源等;

五、应用环境

对于Property和Environment源码设计体系,参考上述的源码模块,在思路上是相似的,此处不多描述;

6.png

应用程序的属性和环境涉及到的参数描述非常多,比较直接的手段是通过System类中的方法输出,至于信息如何加载,在StandardEnvironment类中提供了方法,可以断点查看;

六、Bean对象

基于Spring框架的应用程序中,由Spring容器负责创建,装配,设置属性,进而管理整个生命周期的对象,称为Bean对象;Bean的生命周期非常复杂,过程大致如下:实例化,属性加载,初始化前后管理,销毁;

7.png

BeanFactory:工厂类,Spring框架的核心能力,Bean容器的顶级接口,提供了一系列Bean对象的访问方法,是IOC思想和依赖注入的基础支撑;

ConfigurableBeanFactory:Bean容器可配置化接口,该扩展接口只是为了允许框架内部的即插即用和访问bean工厂的配置方法;

AbstractBeanFactory:Bean管理的抽象实现类,可以查看其内部doGetBean方法,提供Bean实例对象的获取逻辑,如果无法获取则执行创建逻辑;

七、Tomcat服务

初次启动SpringBoot工程时,最大的疑问就是可见Tomcat启动日志,但是没有显式的做服务器装配,直接启动JAR包即可,这在流程上简化了一大步;

8.png

WebServer:Web应用服务器接口,比如常用的Tomcat,Jetty,Netty等,根据应用类型选择,只提供了启动、停止、获取端口三个方法,通过WebServerApplicationContext与应用上下文相关联;

TomcatWebServer:SpringBoot框架管理内置Tomcat服务的核心类,对Tomcat生命周期的管理提供了一层包装;

Tomcat:Apache组件中轻量级Tomcat启动器,提供了Tomcat基础配置,比如默认的Port和HostName,以及生命周期管理的方法,TomcatWebServer类中调用的就是该API中的具体方法;

八、事件模型

事件驱动模型是复杂流程中的常用解耦手段,即通过事件发送和监听两个拆解动作,实现流程的分步执行,这在SpringBoot启动流程和上下文装载中更是发挥的淋漓尽致;

9.png

ApplicationEvent:应用事件基础抽象类,继承自JDK中EventObject类,具体事件会继承该类,内部声明了事件源和发生时间两个核心属性;

ApplicationEventMulticaster:应用事件广播的顶级接口,可以将指定的应用事件广播给适合的监听器;

SimpleApplicationEventMulticaster:应用事件广播接口的简单实现,可以断点该类的multicastEvent方法,查看广播时应用事件和其相应的监听器;

ApplicationListener:应用事件监听器接口,继承自JDK中EventListener接口,Spring中扩展了多种具体的事件监听器,以实现各种不同的场景需求,比如最常见的ConfigFileApplicationListener配置文件监听器;

九、配置加载

SpringBoot工程中,配置文件的管理策略非常复杂,有内部程序执行加载配置,也有外部集成的组件配置,当然最核心的就是工程的自定义配置;

10.png

ConfigFileApplicationListener.Loader:配置文件监听器的内部类,实现对工程中的配置源加载,其核心逻辑在Loader.load方法中实现,具体逻辑由相关的实现类完成;

PropertySourceLoader:配置加载的策略接口,在Spring工程中支持多种类型的文件配置,比如yml、yaml、properties、xml,需要通过文件的扩展名选择相应的加载实现类;

YamlPropertySourceLoader:加载.yml或者.yaml类型的文件,SpringBoot工程中常用的配置文件类型,最终转换成Name和Value的属性源集合,即通过PropertySource抽象类来描述;

十、数据库集成

Spring框架的强大之处还在于能够和其他组件进行简单快速的集成,比如常用的数据库、缓存、消息队列等各种类型的组件,分析内部的集成逻辑,会发现很多原理上的相似性,尤其在SpringBoot框架中,约定大于配置;

11.png

DataSourceAutoConfiguration:SpringBoot工程中数据库的自动化配置类,在配置中Hikari是默认选择的连接池,也是号称速度最快的;

DataSourceProperties:数据源配置相关的基础类,在DataSourceConfiguration配置类中,会基于参数去创建数据源对象;

HikariDataSource:Hikari连接池组件中的数据源API,描述数据源的具体信息,例如配置、连接池、状态等,具体的数据库连接逻辑是在该组件内部完成的;

基于SpringBoot集成数据库的原理,可以扩展性的看看:Redis组件的RedisAutoConfiguration配置类;Kafka组件的KafkaAutoConfiguration配置类,Elasticsearch组件的RestClientAutoConfiguration配置类,在设计原理上都有异曲同工之妙;

写在最后

从个人经验来看,想要阅读Spring框架的源码设计,需要基于应用流程先构建一个大的轮廓结构,理解设计中的常用策略和原理,然后再深入单个模块的细节逻辑,这样容易找到阅读节奏;

本文并没有涉及源码中过多的细节逻辑,只是从服务启动作为切入点,整理与开发关联性较为直接的源码模块,描述个人对于Spring源码阅读的基础思路。

十一、参考源码

应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent

组件封装:
https://gitee.com/cicadasmile/butte-frame-parent
相关文章
|
1月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
2月前
|
前端开发 Java
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
文章通过一个表白墙/留言墙的初级SpringBoot项目实例,详细讲解了如何进行前后端开发,包括定义前后端交互接口、创建SpringBoot项目、编写前端页面、后端代码逻辑及实体类封装的全过程。
106 3
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
2月前
|
前端开发 Java 数据安全/隐私保护
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
文章通过一个简单的SpringBoot项目,详细介绍了前后端如何实现用户登录功能,包括前端登录页面的创建、后端登录逻辑的处理、使用session验证用户身份以及获取已登录用户信息的方法。
417 2
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
|
3天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
13天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
78 13
|
21天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
1月前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
2月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
211 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
2月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
78 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
2月前
|
机器学习/深度学习 移动开发 自然语言处理
基于人工智能技术的智能导诊系统源码,SpringBoot作为后端服务的框架,提供快速开发,自动配置和生产级特性
当身体不适却不知该挂哪个科室时,智能导诊系统应运而生。患者只需选择不适部位和症状,系统即可迅速推荐正确科室,避免排错队浪费时间。该系统基于SpringBoot、Redis、MyBatis Plus等技术架构,支持多渠道接入,具备自然语言理解和多输入方式,确保高效精准的导诊体验。无论是线上医疗平台还是大型医院,智能导诊系统均能有效优化就诊流程。