SpringBoot启动类源码解析

mac2022-06-30  10

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

1、注解:@SpringBootApplication

2、run方法:SpringApplication.run()

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

一、注解:@SpringBootApplication

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

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

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

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

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

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

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

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

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

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

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

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

二、run方法:SpringApplication.run()

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

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

我们再点进去this:

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

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

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

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

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

接下来

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

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

这个方法代码大体意思:

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

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

点入:loadSpringFactories方法中:

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

 

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

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

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

比如我们来看看WebMvcAutoConfiguration

 

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

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

 

最新回复(0)