该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读

Spring Boot 版本:2.2.x

最好对 Spring 源码有一定的了解,可以先查看我的 《死磕 Spring 之 IoC 篇 - 文章导读》 系列文章

如果该篇内容对您有帮助,麻烦点击一下“推荐”,也可以关注博主,感激不尽~

序言

前面一系列的文章对 MyBatis、Spring MVC、Spring IoC、Spring AOP 和 Spring TX 的源码进行了比较详细的分析,不知道各位小伙伴看了多少内容。我想,学习源码是一个比较枯燥乏味的过程,需要静下心来学习,你也许会感觉学不到什么,所以会有多少小伙伴认真看这种文章呢?不管怎样,还是希望文章对你有帮助。???? 我呢,还是本着学习与分享的目的,继续我的知识分享,希望能够一直坚持下去。

现如今,Spring BootSpring 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 过程需要下载非常多的依赖,请耐心等待。

可能遇到的问题

  1. 在根目录的 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>
    
  2. 对整个工程进行编译的过程中出现 rabbit 相关包没有权限拉取的错误,可修改根目录 pom.xmlrabbit-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>
    
  3. 如果编译的过程中还出现 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 项目的实现,包含了许多个子模块,如下:

  1. spring-boot(核心):Spring Boot 的核心实现,根据包名可以知道哪些功能是在哪些包下实现的

  2. spring-boot-autoconfigure(核心):Spring Boot 自动配置的实现,也就是在 Spring 中很多需要通过 XML 配置的类在这里会通过注解进行配置注入(如果可以的话),自动配置,简化 Spring 应用

  3. spring-boot-starters(核心):提供许多常用组件的 Starter 模块,没有相关 Java 代码,仅仅是一个 pom.xml 文件,里面引入组件的相关依赖,帮助我们快速引入组件并使用;通常一个 Spring Boot Starter 需要结合 autoconfigure 自动配置一起引入,这样就能够快速启动

  4. spring-boot-test:提供单元测试的支持

  5. spring-boot-test-autoconfigure:提供单元测试的自动配置功能

  6. 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 模块中的启动方法,后面会讲到~

  7. spring-boot-devtools:提供应用热部署的支持

  8. spring-boot-actuator:提供对我们的应用健康检查和监控的功能

  9. spring-boot-actuator-autoconfigure:提供 spring-boot-actuator 自动配置功能

  10. spring-boot-parent:无 Java 代码,仅一个 pom.xml 文件,是其他子模块的 parent

    我们可以设置自己项目的 parentspring-boot-parent 来引入 Spring Boot

  11. spring-boot-dependencies:无 Java 代码,仅一个 pom.xml 文件,是 spring-boot-parentparent,里面配置了当前 Spring Boot 版本对应其他组件的版本信息

    我们可以添加 spring-boot-dependencies 依赖来引入 Spring Boot(推荐)

代码统计

通过 IDEA Statistic 插件,分别统计了一下两个模块的代码量,如下:

spring-boot

精尽Spring Boot源码分析 - 序言_spring

spring-boot-autoconfigure

精尽Spring Boot源码分析 - 序言_源码解析_02

可以看到这两个模块加起来的代码有点多,不过除去注释什么的也没多少????,既然我们都看过 Spring Framework 了,这也不算什么了????

接下来,开始我们的 Spring Boot 源码学习之旅????‍????