Spring Boot 自动配置及 Factories 机制总结
Spring Boot 应用中的”自动配置”是通过 @EnableAutoConfiguration
注解进行开启的。@EnableAutoConfiguration
可以帮助 Spring Boot 应用将所有符合条件的 @Configuration
配置类的 bean 都加载到 Spring IoC 容器中。本文解析了实现这个效果的原理。
自动配置的原理
Spring Boot 应用的自动配置流程如下:
Spring Factories 机制
首先,注解的实现类使用了 spring-core 中的加载类 SpringFactoriesLoader
加载指定配置,详见文档:
SpringFactoriesLoader loads and instantiates factories of a given type from “META-INF/spring.factories” files which may be present in multiple JAR files in the classpath. The spring.factories file must be in Properties format, where the key is the fully qualified name of the interface or abstract class, and the value is a comma-separated list of implementation class names.
该类会通过类加载器从 classpath 中搜索所有 META-INF/spring.factories
配置文件,然后获取 key 为 org.springframework.boot.autoconfigure.EnableAutoConfiguration
部分。
例如 spring-boot-autoconfigure.jar/META-INF/spring.factories
:
1 | # Auto Configure |
加载结果如图:
继续加载 key 为 org.springframework.boot.autoconfigure.AutoConfigurationImportFilter
部分:
1 | # Auto Configuration Import Filters |
执行条件注解
针对这 118 个候选的 Auto Configure,执行 Import Filters 对应的条件注解:
OnClassCondition
1
2
3
4
5
6
7
8// 底层实现,加载成功则返回 true;加载失败则抛出 java.lang.ClassNotFoundException,捕获异常后返回 false
private static Class<?> forName(String className, ClassLoader classLoader)
throws ClassNotFoundException {
if (classLoader != null) {
return classLoader.loadClass(className);
}
return Class.forName(className);
}OnBeanCondition
判断指定的 bean 类或名称是否已存在于
BeanFactory
。
过滤结果如下:
TRACE
日志如下:
1 | Filtered 30 auto configuration class in 1000 ms |
总结
在日常工作中,我们可能需要实现一些 Spring Boot Starter 给被人使用,这个时候我们就可以使用这个 Factories 机制,将自己的 Starter 注册到 org.springframework.boot.autoconfigure.EnableAutoConfiguration
命名空间下。这样用户只需要在服务中引入我们的 jar 包即可完成自动加载及配置。Factories 机制可以让 Starter 的使用只需要很少甚至不需要进行配置。
本质上,Spring Factories 机制与 Java SPI 机制原理都差不多:都是通过指定的规则,在规则定义的文件中配置接口的各种实现,通过 key-value 的方式读取,并以反射的方式实例化指定的类型。
spring.factories 已废弃
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.7-Release-Notes
Loading auto-configurations from
spring.factories
is deprecated.
If you have created your own auto-configurations, you should move the registration from
spring.factories
to a new file namedMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
. Each line contains the fully qualified name of the auto-configuration. See the included auto-configurations for an example.For backwards compatibility, entries in
spring.factories
will still be honored.
《提升维护效率,利用开源项目 mica-auto 自动生成这两个文件》
https://mp.weixin.qq.com/s/ASBRANcdMI2VXflyvD6wiA
参考
《Spring Boot spring.factories vs @Enable annotations》