来学习SpringBoot启动器原理,我们先从这两个方面来入手:

1、注解:@SpringBootApplication

2、run方法:SpringApplication.run()

在创建SpringBoot应用时,我们都会写这两个东西,我们来仔细看一下它到底是什么

springboot启动类启动自定义类 springboot启动类怎么写_springboot启动类启动自定义类

一、注解:@SpringBootApplication

springboot启动类启动自定义类 springboot启动类怎么写_加载_02

我们可以发现,SpringBootApplication就是一个接口,在这个接口的上面有几个元注解,需特别注意的是这几个注解:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
		@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

我们点进入第一个注解:@SpringBootConfiguration

springboot启动类启动自定义类 springboot启动类怎么写_springboot启动类启动自定义类_03

发现@Configuration注解,所以这是一个配置类,这就想起了我们当时在学习Spring的时候,配置Spring的bean容器有两种配置方式,一种是javaConfig配置类,另外一种就是xml文件来配置,而这里就是声明了一个配置类,然后Spring会自动扫描到添加了`@Configuration`的类,并且读取其中的配置信息。而`@SpringBootConfiguration`是来声明当前类是SpringBoot应用的配置类,项目中只能有一个。所以一般我们无需自己添加。

我们点进入第二个注解:@EnableAutoConfiguration

springboot启动类启动自定义类 springboot启动类怎么写_加载_04

我们来看看注释是怎么描述的?

springboot启动类启动自定义类 springboot启动类怎么写_Web_05

开启自动配置的开关,尝试着去猜测你可能需要的bean,这个注解可以去检测classpath下面你定义的bean或者你引入了什么依赖

我们点进入第三个注解:@ComponentScan

springboot启动类启动自定义类 springboot启动类怎么写_springboot启动类启动自定义类_06

点进去后我们发现,好像也就是这样,没有啥,我们再来看看它的注释

springboot启动类启动自定义类 springboot启动类怎么写_类加载器_07

大概意思就是:这个配置是扫描哪些配置类的,或者扫描那些以XML形式Spring的bean元素(难道没有想起来当时做SSM时Spring的配置文件中的`<context:component-scan>标签,对,差不多就是这样的)

通过basePackageClasses或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包

而我们的@SpringBootApplication注解声明的类就是main函数所在的启动类,因此扫描的包是该类所在包及其子包。因此,一般启动类会放在一个比较前的包目录中。
 

二、run方法:SpringApplication.run()

点进去之后,我们在SpringApplication这个类下面发现,把当前的主类当做参数传递下去,并且又new了一个SpringApplication

springboot启动类启动自定义类 springboot启动类怎么写_类加载器_08

点进去这个SpringApplication的构造函数之后:

springboot启动类启动自定义类 springboot启动类怎么写_springboot启动类启动自定义类_09

我们再点进去this:

springboot启动类启动自定义类 springboot启动类怎么写_springboot启动类启动自定义类_10

我们可以看到,首先定义了一个资源类加载器resourceLoader、然后把该类放在了一个集合里,判断当前应用的类型

我们查看上幅图的下半部分的那个函数:

springboot启动类启动自定义类 springboot启动类怎么写_Web_11

springboot启动类启动自定义类 springboot启动类怎么写_Web_12

判断你的应用是不是包含这些依赖,如果类型和这些都相同,那么你的类型就是WebApplicationType.REACTIVE响应式编程类型

如果不是就会判断的应用是不是Web类型?

springboot启动类启动自定义类 springboot启动类怎么写_加载_13

如果是Web类型,那么就会返回你的Web类型

接下来

setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));

获取Spring的工厂实例,我们点进入:

springboot启动类启动自定义类 springboot启动类怎么写_Web_14

这个方法代码大体意思:

获取了当前类的类加载器,然后加载工厂的名字,并把名字放到set集合里,随后通过传入的names,以反射的方式来创建实例

我们先来看,它获取了哪些类的名字,也就是我们看看loadFactoryNames里面到底有什么?

springboot启动类启动自定义类 springboot启动类怎么写_Web_15

点入:loadSpringFactories方法中:

springboot启动类启动自定义类 springboot启动类怎么写_加载_16

我们可以看到它是通过类加载器来加载,分为对象加载和静态方法加载。我们看看它加载的是什么?

springboot启动类启动自定义类 springboot启动类怎么写_加载_17

 

我们发现classpath下面并没有这个文件目录,所以我们可以去找jar,所以在依赖的jar包下面找到了

springboot启动类启动自定义类 springboot启动类怎么写_Web_18

我们就来看看这个Spring.factories到底是什么?

springboot启动类启动自定义类 springboot启动类怎么写_加载_19

原来这个文件里都是需要的一些接口或者类,他们的共同就是都有autoConfiguration

springboot启动类启动自定义类 springboot启动类怎么写_Web_20

比如我们来看看WebMvcAutoConfiguration

springboot启动类启动自定义类 springboot启动类怎么写_springboot启动类启动自定义类_21

 

根据@Conditional注解来判断是否启用了该注解。

如果自己想覆盖一些注解,可以通过在yml文件中直接通过key和value来覆盖