文章目录
一、POM文件分析
【1】父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
</parent>
<!--
org.springframework.boot他的父项目是spring-boot-dependencies
他来真正管理Spring Boot应用里面的所有依赖版本;
Spring Boot的版本仲裁中心;
以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>

【2】场景启动器
场景启动器的作用就是封装了相关场景要用到的依赖,这里以web启动器为例。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter:spring-boot场景启动器;帮我们导入了web模块正常运行所依赖的组件; Spring
Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器。
二、自动装配的源码剖析
【1】@SpringBootApplication
作用:标注SpringBoot主程序类,主入口类
/*
* @SpringBootApplication用来标注一个主程序类,说明这是一个SpringBoot应用
*/
@SpringBootApplication
public class Demo03Application {
public static void main(String[] args) {
SpringApplication.run(Demo03Application.class, args);
}
}
@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,
SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;
我们点击进入这个注解,发现这个注解由以下几个注解组成,说明这是一个组合注解,并且集成了这些组成注解的所有功能。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
下面讲解这几个注解。
(1)@SpringBootConfiguration
作用:标注在某个类上,表示这是一个Spring Boot的配置类,此注解由下面的注解组成。
@Configuration
public @interface SpringBootConfiguration {
@Configuration:标注这个注解表示Spring的配置类,相当于Spring的xml配置文件的<beans></beands>。
(2)@EnableAutoConfiguration
作用:标注表示Spring Boot开启自动配置功能
这是SpringBoot自动配置的核心!
以前我们需要配置的东西, Spring Boot帮我们自动配置; @EnableAutoConfiguration告诉
SpringBoot开启自动配置功能;这样自动配置才能生效,此注解由下面的注解组成。
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
– @AutoConfigurationPackage
作用:标注表示自动配置包
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
– @lmport
@lmport(AutoConfigurationPackages.Registrar.class) 相当于Spring的xml配置文件中的元素,给容器中导入一个组件;导入的组件是: AutoConfigurationPackages.Registrar.class 。
作用是将筛选好的组件注册到IOC容器中。
– @Import({AutoConfigurationImportSelector.class})
作用:导入组件AutoConfigurationImportSelector.class,选择导入哪些选择器。

这个方法将要导入的组件以全类名字符串的方式返回,这些组件就会被添加到容器中,这个方法里面还调用了另一个方法,进入该方法我们断点调试一下。

到这里一步可以看到configurations的值,一共是127个组件。
我们看一下这个方法做了什么,进入该方法。
点击这个方法
点击这个方法
可以看到该方法对资源路径进行了扫描,并且将扫描到的文件内容包装成了一个个的Properties对象

这个文件的位置
文件内容,这部分就是SpringBoot自带的全部组件的全类名,一共是127个
这些组件后面都有一个AutoConfiguration,表示是SpringBoot自带的自动配置类。
点到这里进去:


这一步的作用就是从properties中获取到EnableAutoConfiguration. class类(类名)对应的值,然后把他们添加在容器中。这些组件就是自动配置类,利用它们来做自动配置,每一个自动配置类都有相应的自动配置。
这里以HttpEncodingAutoConfiguration为例解释自动配置原理
(1)找到上文提到的资源文件,进入该类
@Configuration( //
proxyBeanMethods = false
)
@EnableConfigurationProperties({ServerProperties.class}) //启动指定类的ConfigurationProperties功能,将配置文件配置的值和该类的属性绑定起来
@ConditionalOnWebApplication( //Spring底层@Conditional注解, 根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效,这里是判断当前应用是否是web应用,如果是,当前配置类生效
type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class}) //判断当前项目有没有这个类CharacterEncodingFilter:SpringMVC中进行乱码解决的过滤器;
@ConditionalOnProperty( // 判断配置文件中是否存在某个配置server.servlet.encoding.enabled ;如果不存在,判断也是成立的。意思就是即使我们配置文件中不配置server.servlet.encoding.enabled,enabled也是默认为true;
prefix = "server.servlet.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
(2)点进ServerProperties类
@ConfigurationProperties(
prefix = "server",
ignoreUnknownFields = true
)
public class ServerProperties {
private Integer port;
private InetAddress address;
@NestedConfigurationProperty
private final ErrorProperties error = new ErrorProperties();
private ServerProperties.ForwardHeadersStrategy forwardHeadersStrategy;
private String serverHeader;
private DataSize maxHttpHeaderSize = DataSize.ofKilobytes(8L);
private Shutdown shutdown;
@NestedConfigurationProperty
private Ssl ssl;
@NestedConfigurationProperty
private final Compression compression;
@NestedConfigurationProperty
private final Http2 http2;
private final ServerProperties.Servlet servlet;
private final ServerProperties.Tomcat tomcat;
private final ServerProperties.Jetty jetty;
private final ServerProperties.Netty netty;
private final ServerProperties.Undertow undertow;
我们发现这里面有很多的属性,而这些属性,正是我们可以在配置文件配置的东西。
所有在配置文件中能配置的属性都是在xxxProperties类中封装着,配置文件能配置什么就可以参照某个功能对应的这个类的属性。
自动配置精髓:
1). SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
3)、我们再来看这个自动配置类中到底配置了哪些组件; (只要我们要用的组件有,我们就不需要再来配置
了)
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指
定这些属性的值;
xxxxAutoConfigurartion:自动配置类;
给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
(3)@ComponentScan
作用:将主配置类( @SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
由此我们可以知道,如果SpringBoot启动类没有和要被扫描的类有共同的父包,那么就无法扫描到。
三、SpringBoot启动过程源码剖析
这里有一位大佬讲的非常详细,大家可以看他的博客。
https://blog.youkuaiyun.com/weixin_43570367/article/details/104960677
本文详细剖析了SpringBoot2.3.3的源码,包括POM文件分析、自动装配过程以及启动过程。重点讲解了@SpringBootApplication的组成,如@SpringBootConfiguration、@EnableAutoConfiguration及其内部机制,尤其是自动配置类如何通过@ImportSelector加载,并结合配置文件完成组件的自动配置。此外,还提到了@ComponentScan的作用,即扫描主配置类所在包及子包中的组件。

407

被折叠的 条评论
为什么被折叠?



