Springboot 自动配置原理/源码解析

本文详细解析了Spring Boot自动配置的原理,从@SpringBootApplication注解开始,涉及@Configuration、@ComponentScan和@EnableAutoConfiguration的作用。通过源码剖析,展示了如何从spring.factories文件中自动加载配置类并进行属性注入。
摘要由CSDN通过智能技术生成

目录

1、自动配置读取原理源码解析

(1)@SpringBootConfiguration 

(2)@ComponentScan

(3)@EnableAutoConfiguration

2、Springboot 自动配置类的使用


Spring Boot 自动配置流程图示

1、自动配置读取原理源码解析

@SpringBootApplication 注解开始,Spring Boot 应用把该注解标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot 需要运行这个类的 main() 方法来启动 SpringBoot 应用;

@SpringBootApplication 注解由以下注解组成

关于Java元注解,可以查看这篇文章《Java注解解析和使用

(1)@SpringBootConfiguration 

@SpringBootConfiguration  标注在某个类上,表示这是一个Spring Boot的配置类;@SpringBootConfiguration 注解详情如下

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // 标记为配置类
public @interface SpringBootConfiguration {
}

(2)@ComponentScan

@ComponentScan 包扫描注解,相当于 spring.xml 配置中的 <context:component-scan base-package="com.xxx.xxx" />,如果没有指定 basepackage,会自动扫描当前注解配置类所在的包和所在包下的所有子包。// 所以被@SpringBootApplication 标注的类总是放置在项目的最外层包

(3)@EnableAutoConfiguration

@EnableAutoConfiguration 自动配置注解,自动配置的核心注解,详情如下

@AutoConfigurationPackage 注解,负责保存标注相关注解的类的所在包路径。使用一个BasePackage类,保存这个路径。然后使用 @Import 注解将其注入到 ioc 容器中。随后,Spring 可以在容器中拿到该路径。

@Import 注解只能用在类上 ,通过快速导入的方式实现把实例加入 spring 的 IOC 容器中

SpringBoot 通过 @Import  注解导入了一个 AutoConfigurationImportSelector.class 的类

@Import(AutoConfigurationImportSelector.class)

AutoConfigurationImportSelector.class 实现了 DeferredImportSelector 接口(DeferredImportSelector 是 ImportSelector 的一种), 在 ImportSelector  接口中 ImportSelector#selectImports() 方法会返回一个字符串数组(实际上就是 SpringBean 的完整限定名),Spring 底层会根据这些完整限定名,将类注册成 Bean 放到 IOC容器中

DeferredImportSelector#selectImports() 方法的执行逻辑:如果实现类实现了 getImportGroup() 方法(返回值不为空且实现了DeferredImportSelector.Group),那么就调用 Group 类中的selectImports() 方法,否则调用实现类的 selectImports() 方法。

SpringBoot 中 AutoConfigurationImportSelector 实现了 getImportGroup() 方法,返回了一个AutoConfigurationGroup.class

AutoConfigurationGroup.class 中,会先调用 process() 方法获取自动配置类,然后调用 selectImports() 方法把获取到的自动配置类封装成 Iterable<Entry> 返回

在 AutoConfigurationGroup#process 中,process#getAutoConfigurationEntry会获取到所有的自动配置类

process#getAutoConfigurationEntry 中会获取所有的候选配置,然后通过一系列筛选才返回最终的自动配置类

getAutoConfigurationEntry#getCandidateConfigurations 真正的去获取配置类,那么它是怎么获取这些配置文件的呢?

使用 getCandidateConfigurations#loadFactoryNames 加载配置文件

loadFactoryNames 中的详细执行逻辑如下,它会去加载 META-INF/spring.factories ,获取这个文件中的所有内容,然后只返回与 factoryClassName 匹配的所有 List<String> ;

至此,SpringBoot 自动配置的读取流程就已经完成了。

附:

每一个 SpringBoot 应用,都会引入 spring-boot-autoconfigure.jar ,jar包中 META-INF/ 目录下包含一个 spring.factories 文件。spring.factories 文件中数据以 Key=Value 形式存在,多个 Value 时使用 "," 隔开,该文件中定义了关于初始化,监听器等信息。其中真正使自动配置类生效的 key 是 org.springframework.boot.autoconfigure.EnableAutoConfiguration ,如下所示:

为什么会是 org.springframework.boot.autoconfigure.EnableAutoConfiguration ?

还记得使用 getCandidateConfigurations#loadFactoryNames 加载配置文件这个方法吗?

其中有一个参数是通过 getSpringFactoriesLoaderFactoryClass() 获取的,这个方法的会返回一个EnableAutoConfiguration

这个 EnableAutoConfiguration 就是 org.springframework.boot.autoconfigure.EnableAutoConfiguration

然后 loadFactoryNames 会根据这个 EnableAutoConfiguration 的名字做为筛选条件,把所有的 xxxAutoConfiguration 封装成一个 List<String> 集合

每一个这样的 xxxAutoConfiguration 类都是容器中的一个组件,xxxAutoConfiguration 类中的Bean 会加入到 IOC 容器中,从而实现自动配置。

注:@EnableAutoConfiguration 注解,通过 @SpringBootApplication 被间接的标记在了 SpringBoot 的启动类上。在 SpringApplication.run(...) 内部就会执行 selectImports() 方法,从而找到所有JavaConfig 自动配置类的全限定名对应的class,然后将所有自动配置类加载到 Spring 容器中。

2、Springboot 自动配置类的使用

以 HttpEncodingAutoConfiguration 自动配置文件为例

在 spring-boot-autoconfigure.jar 的 spring.factories 文件中,有这样一行配置:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
// 省略...
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
// 省略...

HttpEncodingAutoConfiguration.class 文件的内容如下

其中  HttpProperties.class 里边的属性就是我们通过 application.properties 可以配置的属性

@ConfigurationProperties(prefix = "spring.http") // 绑定外部配置文件的命名属性

假如,我们在 application.properties 中配置如下属性

那么 SpringBoot 启动时,会自动加载到这个属性的值 

至此,完成一个自动配置的属性注入。

Spring Boot自动装配原理可以分为以下几个关键步骤: 1. 启动过程:在Spring Boot应用启动时,会执行SpringApplication类的run方法。该方法会创建Spring应用上下文,并触发自动装配过程。 2. 自动装配过程:自动装配过程主要依赖于条件注解和自动配置类。 - 条件注解:Spring Boot提供了一系列条件注解,如@ConditionalOnClass、@ConditionalOnBean、@ConditionalOnProperty等。这些注解可以根据特定的条件来决定是否进行自动配置。 - 自动配置类:自动配置类使用@Configuration注解进行标识,通过@Bean注解来声明需要自动配置的Bean。自动配置类通常使用@Conditional注解来指定条件,只有当满足条件时才会生效。 3. 自动配置类的加载:Spring Boot自动扫描项目中的META-INF/spring.factories文件,该文件中定义了需要自动配置的类。Spring Boot会根据这些类的条件进行加载和实例化。 4. Bean的创建:在自动配置类中使用@Bean注解声明的Bean会被Spring容器自动创建和管理。这些Bean的创建过程会经过Spring的各个处理器,如BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor等。 下面是一个简单的示例来说明Spring Boot自动装配的原理: ```java @Configuration @ConditionalOnClass(MyService.class) public class MyAutoConfiguration { @Bean public MyService myService() { return new MyService(); } } ``` 在上述示例中,@ConditionalOnClass注解表示只有当MyService类在类路径中存在时,该自动配置类才会生效。当应用启动时,Spring Boot会扫描到该自动配置类,并根据条件判断是否需要进行自动配置。如果满足条件,Spring Boot会实例化并管理MyService的Bean。 通过自动装配,Spring Boot可以根据项目的实际需求,自动配置和管理各种Bean,从而减少了开发人员的配置工作,提高了开发效率。 请注意,上述示例只是简单示意,并不涵盖所有细节。实际的自动装配过程还涉及到条件判断、依赖关系处理、配置属性绑定等复杂的逻辑。如果你想深入了解Spring Boot自动装配原理,建议阅读Spring Boot源码以及相关文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值