Introduction

我们知道,SpringBoot之所以强大,就是因为他提供了各种默认的配置,可以让我们在集成各个组件的时候从各种各样的配置文件中解放出来。

拿一个最普通的 web 项目举例。我们需要使用 servlet 容器,SpringBoot 就提供了嵌入式的 Tomcat 作为默认容器,不需要一行配置就能直接以最普通的 Java 程序的方式启动:java -jar;接收请求需要一个网络端口,默认配置好8080;处理请求需要 servlet 的多线程特性,默认配置好了最大线程数为200;处理好的请求以Restful 风格返回给调用方,SpringBoot 默认配置好了jackson进行 json 序列化,业务代码需要做的只是返回一个 POJO 对象;连接池直接就默认配置了性能最好的的 Hikari,以及连接池的默认尺寸为10……在一个简单的web应用中,这些配置我们甚至都可能不了解或者没有意识到它们的存在,就可以让程序正常运行。

这就是自动配置的魔力——润物细无声。

那么自动配置是怎么实现的呢?本文就从POM文件和 @SpringBootApplication 注解来简单分析一下自动配置原理。

真的只是简单地,分析一下。

POM文件

环境

  • SpringBoot 2.0.6

父项目

在每一个 SpringBoot 项目一开始的 POM 文件中,就有一个父依赖

<parent>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-parent</artifactId>   <version>2.0.6.RELEASE</version>   <relativePath/> <!-- lookup parent from repository --> </parent>

点进artifactId之后来到 spring-boot-starter-parent-2.0.6.RELEASE.pom 文件,这个文件还有一个父依赖:

<parent>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-dependencies</artifactId>   <version>2.0.6.RELEASE</version>   <relativePath>../../spring-boot-dependencies</relativePath> </parent>

再继续点进去来到 spring-boot-dependencies-2.0.6.RELEASE.pom 文件中。在该文件的 <properties> 标签中可以看到各种各样的组件的版本信息, <dependencyManagement> 标签中声明了各个组件的maven坐标信息。其中,我数了一下,在 SpringBoot 2.0.6 中一个有177个带有版本信息的组件名,包括了大家熟悉的 elasticsearch、activemq、redis、kafka等等。

这里(spring-boot-dependencies-2.0.6.RELEASE.pom文件)称为 SpringBoot 的“版本仲裁中心”,它是用来管理 SpringBoot 应用里面的所有依赖版本的地方。 它包含了大部分开发中会用到的一些组件的版本,所以我们导入依赖默认是不需要写版本号的,SpringBoot 会自动帮我们配置需要的版本。这样在引入某个组件的时候不用考虑这个组件和系统中已有的组件兼不兼容之类的问题,避免了烦人的版本冲突问题。(当然,没有在 dependencies里面管理的依赖自然需要声明版本号)

启动器(Starters)

父项目做版本仲裁,那么真正的 jar 包是从哪里导入进来的呢?这就要说到我们的starters了。点开web-starter可以看到它帮我们导入了web模块正常运行所依赖的组件,就不用我们一个一个手动导入了。

所以,所谓的Starters就是一系列依赖描述的组合,我们可以通过导入这些starters就会有相应的依赖了并可以基于他们进行相应的开发

Springboot把开发中中会遇到的场景都抽象成一个个的starter,比如(),只需要在项目里面引入这些starter 相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器

@SpringBootApplication

一个典型的 springboot 项目的入口类如下所示:

@SpringBootApplication