spring.factories和org.springframework.boot.autoconfigure.AutoConfiguration.imports都是Spring Boot自动配置机制中的重要组成部分
一、spring.factories文件
位于 resources/META - INF 目录下,主要作用不仅可以用来注册自动配置类,还可以用来注册各种其他类型的处理器和服务提供者
文件中的内容是一系列的键值对,其中键是接口或抽象类的全限定名,值是这些接口或抽象类的实现类的全限定名列表
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.example.autoconfig.AutoConfiguration1,
com.example.autoconfig.AutoConfiguration2
这表示当 EnableAutoConfiguration 接口被触发(在 Spring Boot 启动时默认会触发)时,AutoConfiguration1 和 AutoConfiguration2 这两个自动配置类会被加载并执行它们的配置逻辑,这些自动配置类通常会包含创建 Bean、配置属性等操作,用于初始化应用所需的各种组件
二、org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件
这是 Spring Boot 3.0 引入的一种新的自动配置导入方式,用于替代部分 spring.factories 文件的功能(但并不是完全替代),它主要用于更简洁地指定需要导入的自动配置类。
在 Spring Boot 3.0 及以后的版本中,当应用启动时,会查找并读取 resources/META - INF/spring 目录下的 AutoConfiguration.imports 文件,这个文件中的每一行都是一个自动配置类的全限定名,这些类会被直接导入并应用配置
com.example.autoconfig.AutoConfiguration1
com.example.autoconfig.AutoConfiguration2
三、注意事项
1.自动装配
springboot2.7以前:META-INF/spring.factories
springboot2.7-springboot3.0:同时兼容
springboot3.0以后:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
2.AutoConfiguration.imports 仅适用于自动配置类
不要将普通的 EnvironmentPostProcessor 或其他类型的处理器放入此文件中,对于EnvironmentPostProcessor应该继续使用 META-INF/spring.factories 文件进行注册;可以利用 @AutoConfiguration 和条件注解(如 @ConditionalOn*)系列(如 @ConditionalOnProperty, @ConditionalOnClass, @ConditionalOnMissingBean 等)可以让你的自动配置类只在特定条件下生效,从而实现更加灵活和精确的配置管理
3.META-INF/spring.factories还可以注册不同类型的组件
META-INF/spring.factories 文件是一个更通用的机制,它不仅用于注册自动配置类,还可以用来注册各种其他类型的处理器和服务提供者,比如:
EnvironmentPostProcessor:允许你在应用程序环境初始化阶段执行自定义逻辑;
ApplicationContextInitializer:可以在 ApplicationContext 初始化之前执行一些操作;
ApplicationListener:监听并响应应用程序事件;
ImportSelector 或 ImportBeanDefinitionRegistrar:动态导入额外的配置;
4.为什么 EnvironmentPostProcessor 不适合放在 AutoConfiguration.imports 中?
EnvironmentPostProcessor 实现类主要用于在应用程序环境创建之后但在任何自动配置发生之前进行修改,这包括解析属性、加载额外的配置源等任务,如果将 EnvironmentPostProcessor 放入 AutoConfiguration.imports,可能会导致以下问题时机不匹配:自动配置是在环境已经建立的基础上进行的,而 EnvironmentPostProcessor 需要在环境构建的过程中介入,因此它的处理逻辑应该早于自动配置的执行;
5.读取配置文件源码
springboot3之前
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
springboot3之后
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())
.getCandidates();
Assert.notEmpty(configurations,
"No auto configuration classes found in "
+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}