该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读
Spring Boot 版本:2.2.x
最好对 Spring 源码有一定的了解,可以先查看我的 《死磕 Spring 之 IoC 篇 - 文章导读》 系列文章
如果该篇内容对您有帮助,麻烦点击一下“推荐”,也可以关注博主,感激不尽~
序言
前面一系列的文章对 MyBatis、Spring MVC、Spring IoC、Spring AOP 和 Spring TX 的源码进行了比较详细的分析,不知道各位小伙伴看了多少内容。我想,学习源码是一个比较枯燥乏味的过程,需要静下心来学习,你也许会感觉学不到什么,所以会有多少小伙伴认真看这种文章呢?不管怎样,还是希望文章对你有帮助。 我呢,还是本着学习与分享的目的,继续我的知识分享,希望能够一直坚持下去。
现如今,Spring Boot
和 Spring Cloud
在许多中大型企业中被普及,Java Configuration 成为了主流,XML 配置的方式也逐渐“消失”在我们的视野里面。前面我们已经学完 Spring 相关的源码,那么接下来一起来学习 Spring Boot
的源码,揭开它神秘的面纱。
如果你对 Spring 的源码有比较充分的了解,那么阅读 Spring Boot
的源码会比较轻松,我花了一周左右时间,应该看得差不多了 所以对于 Spring 源码不熟悉的小伙伴,如果有兴趣的话,可以先去看看我前面的一系列文章。
接下来 Spring Boot 系列文章主要分为以下几个部分:
- 调试环境的搭建与项目结构概述
- Spring Boot 应用打成
jar
包的启动实现 - Spring Boot 的
SpringApplication
启动类的启动过程 - Spring Boot 内嵌 Tomcat 容器的实现
- Spring Boot 支持外部 Tomcat 容器的实现
-
@SpringBootApplication
注解的实现原理,也就是 Spring Boot 的@EnableAutoConfiguration
自动配置模块驱动注解的实现原理 - Spring Boot 对于 Condition 接口的扩展
- Spring Boot 的配置加载 - ConfigFileApplicationListener
- Spring Boot 的日志系统 - LoggingApplicationListener
- Spring Boot 的
@ConfigurationProperties
注解的实现
接下来我们先把 Spring Boot 的调试环境搭建好
依赖工具
- Maven 3.6.3
- Git
- JDK 1.8+
- IntelliJ IDEA 2020.1.1
笔者目前使用的是 Windows 系统,如果使用的是系统版本是 MAC OS 或者其他 IDEA 版本,可能会遇到相关问题,需自行 Google 处理。
源码拉取
从 Spring Boot 的 Git 仓库 Fork
项目到自己的 Git 仓库,方便我们在阅读源码的过程中,可添加相应的注释后提交代码。分支建议选择 2.2.x
作为默认分支,因为这个分支使用 Maven 管理依赖包(后续新的版本都是 Gradle),大多数人还是更加熟悉 Maven,所以笔者选择了 2.2.x
这个分支进行源码阅读。
当然,也可以直接拉取我的 Spring Boot 源码分析 GitHub 地址 进行阅读,根据我添加的注释结合我的文章进行阅读,体验更佳。
由于 Spring Boot 项目比较大,从仓库中拉取代码的时间会比较长,因为 Build 过程需要下载非常多的依赖,请耐心等待。
可能遇到的问题
-
在根目录的
pom.xml
看到${disable.checks}
报错,可以添加一个配置,禁用 Maven 代码检查,如下:<properties>
<revision>2.2.14.BUILD-SNAPSHOT</revision>
<main.basedir>${basedir}</main.basedir>
<!-- 禁用 Maven 代码检查 -->
<disable.checks>true</disable.checks>
</properties> -
对整个工程进行编译的过程中出现 rabbit 相关包没有权限拉取的错误,可修改根目录
pom.xml
的rabbit-milestone
仓库配置,如下:<repository>
<id>rabbit-milestone</id>
<name>Rabbit Milestone</name>
<!-- https://dl.bintray.com/rabbitmq/maven-milestones -->
<url>https://repos.spark-packages.org</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository> 如果编译的过程中还出现
Cannot resolve
的错误,可以试着将自己的私有仓库注释掉,使用阿里云的 Maven 仓库。
项目结构概览
整个 spring-boot 工程项目结构如下:
spring-boot
---- spring-boot-project
-------- spring-boot
-------- spring-boot-actuator
-------- spring-boot-actuator-autoconfigure
-------- spring-boot-autoconfigure
-------- spring-boot-cli
-------- spring-boot-dependencies
-------- spring-boot-devtools
-------- spring-boot-docs
-------- spring-boot-parent
-------- spring-boot-properties-migrator
-------- spring-boot-starters
-------- spring-boot-test
-------- spring-boot-test-autoconfigure
-------- spring-boot-tools
-------- pom.xml
---- spring-boot-tests
---- pom.xml
各个子模块的描述:
spring-boot-tests
:项目的测试类
spring-boot-project
:整个 Spring Boot 项目的实现,包含了许多个子模块,如下:
spring-boot
(核心):Spring Boot 的核心实现,根据包名可以知道哪些功能是在哪些包下实现的spring-boot-autoconfigure
(核心):Spring Boot 自动配置的实现,也就是在 Spring 中很多需要通过 XML 配置的类在这里会通过注解进行配置注入(如果可以的话),自动配置,简化 Spring 应用spring-boot-starters
(核心):提供许多常用组件的 Starter 模块,没有相关 Java 代码,仅仅是一个pom.xml
文件,里面引入组件的相关依赖,帮助我们快速引入组件并使用;通常一个 Spring Boot Starter 需要结合 autoconfigure 自动配置一起引入,这样就能够快速启动spring-boot-test
:提供单元测试的支持spring-boot-test-autoconfigure
:提供单元测试的自动配置功能-
spring-boot-tools
:Spring Boot 提供的工具箱例如其中的
spring-boot-maven-plugin
子模块可以帮助我们将自己的项目打成一个 jar 包,还有一个spring-boot-loader
子模块是启动 jar 包的实现,例如java -jar x.jar
(这个 jar 包是 Spring Boot 插件生成的)启动应用时,并不是直接调用我们的main
方法,而是调用spring-boot-loader
模块中的启动方法,后面会讲到~ spring-boot-devtools
:提供应用热部署的支持spring-boot-actuator
:提供对我们的应用健康检查和监控的功能spring-boot-actuator-autoconfigure
:提供spring-boot-actuator
自动配置功能-
spring-boot-parent
:无 Java 代码,仅一个pom.xml
文件,是其他子模块的parent
我们可以设置自己项目的
parent
为spring-boot-parent
来引入 Spring Boot -
spring-boot-dependencies
:无 Java 代码,仅一个pom.xml
文件,是spring-boot-parent
的parent
,里面配置了当前 Spring Boot 版本对应其他组件的版本信息我们可以添加
spring-boot-dependencies
依赖来引入 Spring Boot(推荐)
代码统计
通过 IDEA Statistic 插件,分别统计了一下两个模块的代码量,如下:
spring-boot
:
spring-boot-autoconfigure
:
可以看到这两个模块加起来的代码有点多,不过除去注释什么的也没多少,既然我们都看过 Spring Framework 了,这也不算什么了
接下来,开始我们的 Spring Boot 源码学习之旅