注:该源码分析对应SpringBoot版本为2.1.0.RELEASE
1 温故而知新
本篇接 SpringBoot内置的各种Starter是怎样构建的? SpringBoot源码(六)
温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBootSpringBoot内置的各种Starter是怎样构建的?,现将关键点重新回顾总结下:
spring-boot-starter-xxx
起步依赖没有一行代码,而是直接或间接依赖了xxx-autoconfigure
模块,而xxx-autoconfigure
模块承担了spring-boot-starter-xxx
起步依赖自动配置的实现;xxx-autoconfigure
自动配置模块引入了一些可选依赖,这些可选依赖不会被传递到spring-boot-starter-xxx
起步依赖中,这是起步依赖构建的关键点;spring-boot-starter-xxx
起步依赖显式引入了一些对自动配置起作用的可选依赖,因此会触发xxx-autoconfigure
自动配置的逻辑(比如创建某些符合条件的配置bean
);- 经过前面3步的准备,我们项目只要引入了某个起步依赖后,就可以开箱即用了,而不用手动去创建一些
bean
等。
2 引言
本来这篇文章会继续SpringBoot自动配置的源码分析的,想分析下spring-boot-starter-web
的自动配置的源码是怎样的的。但是考虑到spring-boot-starter-web
的自动配置逻辑跟内置Tomcat
等有关,因此想以后等分析了SpringBoot的内置Tomcat
的相关源码后再来继续分析spring-boot-starter-web
的自动配置的源码。
因此,本篇我们来探究下SpringBoot的启动流程是怎样的?
3 如何编写一个SpringBoot启动类
我们都知道,我们运行一个SpringBoot项目,引入相关Starters
和相关依赖后,再编写一个启动类,然后在这个启动类标上@SpringBootApplication
注解,然后就可以启动运行项目了,如下代码:
//MainApplication.java
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
如上代码,我们在MainApplication
启动类上标注了@SpringBootApplication
注解,然后在main
函数中调用SpringApplication.run(MainApplication.class, args);
这句代码就完成了SpringBoot的启动流程,非常简单。
4 @SpringBootApplication
现在我们来分析下标注在启动类上的@SpringBootApplication
注解,直接上源码:
// SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
// TODO 这两个排除过滤器TypeExcludeFilter和AutoConfigurationExcludeFilter暂不知道啥作用
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
// 等同于EnableAutoConfiguration注解的exclude属性
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[]