SpringBoot自动化配置原理

SpringBoot的出现,得益于"习惯优于配置"的理念,没有繁琐的配置、难以集成的内容(大多数流行第三方技术都能被集成),这是基于Spring 4.x提供的条件配置Bean的能力。

SpringBoot的配置文件

SpringBoot有一个全局配置文件:application.properties或application.yml。
我们的各种属性都可以在这个文件中进行配置,最常配置的比如:server.port、logging.level.*等等,然而实际用到的往往只是很少的一部分,那么这些属性是否有据可依呢?答案当然是肯定的,这些属性都可以在官方文档中查找到:
https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#common-application-properties
在这里插入图片描述
这些配置是如何在SpringBoot项目中生效的呢?

工作原理剖析

SpringBoot关于自动化配置的源码在spring-boot-autoconfigure-x.x.x.x.jar中:
在这里插入图片描述
SpingBoot的启动类上有一个@SpringBootApplication注解,这个注解是SpringBoot项目必不可少的注解。
在这里插入图片描述
@SpringBootApplication是一个复合注解或者派生注解,在@SpringBootApplication中有一个注解@EnableAutoConfiguration(开启自动配置),其定义如下:
在这里插入图片描述
而这个注解也是一个派生注解,其中的关键功能由@Import提供,其导入的AutoConfigurationImportSelector的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories的jar包。spring-boot-autoconfigure-x.x.x.x.jar里就有一个这样的spring.factories文件。、
这个spring.factories文件也是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表,这些类名以逗号分隔,如下图所示:
在这里插入图片描述
这个@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记了SpringBoot的启动类上。在SpringApplication.run(…)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到spring容器中。

自动配置生效

每一个XxxxAutoConfiguration自动配置类都是在某些条件下才会生效的,这些条件的限制在SpringBoot中以注解的形式体现,常见的条件注解由如下几项:

@ConditionalOnBean 当容器里有指定bean的条件下
@ConditionalOnMissingBean 当容器里不存在指定bean的条件下
@ConditionalOnClass 当类路径下有指定类的条件下
@ConditionalOnMissingClass 当类路径下不存在指定类的条件下
@ConditionalOnProperty 指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix="xxx.xxx",value="enable",matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true

以ServletWebServerFactoryAutoConfiguration配置类为例,解释一下全局配置文件中属性如何生效,比如:server.port=8081,是如何生效的(当然不配置也会有默认值,这个默认值来自于org.apache.catalina.startup.Tomcat)。
在这里插入图片描述
在ServletWebServerFactoryAutoConfiguration类上,有一个@EnableConfigurationProperties注解:开启配置属性,
而它后面的参数是一个ServerProperties类,这就是习惯优于配置的最终落地点。
在这里插入图片描述
在这个类上,有一个@ConfigurationProperties,它的作用就是从配置文件中绑定属性到对应的bean上,而@EnableConfigurationProperties负责导入这个已经绑定了属性的bean到Spring容器中,那么所有其他的和这个类相关的属性都可以在全局配置文件中定义,也就是说,真正"限制"我们可以在全局配置文件中配置哪些属性的类就是这些XxxxProperties类。它与配置文件中定义的prefix关键字开头的一组属性是唯一对应的。
至此,我们大致可以了解。在全局配置的属性如:server.port等,通过@ConfigurationProperties注解,绑定到对应的XxxxProperties配置实体类上封装为一个bean,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。
而诸多的XxxxAutoConfiguration自动配置类,就是Spring容器的JavaConfig形式,作用就是为Spring容器导入bean,而所有导入的bean所需要的属性都通过XxxxProperties的bean来获得。

SpringBoot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factiries配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,如:server.port,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。

通过一张图来理解一下这一繁复的流程:
在这里插入图片描述

总结

一定要记得XxxxProperties类的含义是:封装配置文件中相关属性;XxxxAutoConfiguration类的含义是:自动配置类,目的是给容器中添加组件。
而其他的主方法启动,则是为了加载这些五花八门的XxxxAutoConfiguration类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值