Spring Boot 自动配置类加载机制
Spring Boot通过SpringFactoriesLoader机制发现和加载自动配置类,实现约定优于配置。
SpringFactoriesLoader
核心类
Java
public final class SpringFactoriesLoader {
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
public static List<String> loadFactoryNames(Class<?> factoryType,
ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return loadSpringFactories(classLoader)
.getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
// 1. 从缓存获取
// 2. 扫描所有META-INF/spring.factories
// 3. 解析Properties格式
// 4. 缓存结果
}
}
spring.factories文件
文件位置
properties
类路径下所有META-INF/spring.factories
├── spring-boot-autoconfigure.jar!/META-INF/spring.factories
├── my-starter.jar!/META-INF/spring.factories
└── ...
文件格式
Java
# Key: 接口/注解全限定名
# Value: 实现类全限定名,多个用逗号分隔
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
加载流程
1. 启动触发
Java
@EnableAutoConfiguration
-> @Import(AutoConfigurationImportSelector.class)
-> selectImports()
2. 加载候选配置
Java
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
return configurations;
}
3. 去重过滤
Java
// AutoConfigurationImportSelector
Set<String> configurations = new LinkedHashSet<>();
configurations.addAll(getCandidateConfigurations(...)); // 从spring.factories加载
configurations.removeAll(getExclusions(...)); // 移除排除项
configurations = filter(configurations, ...); // 条件过滤
缓存机制
properties
// SpringFactoriesLoader使用ClassLoader作为缓存Key
// 多个ClassLoader可能加载相同的spring.factories多次
private static final Map<ClassLoader, Map<String, List<String>>> cache =
new ConcurrentReferenceHashMap<>();
自定义自动配置注册
properties
# my-starter/src/main/resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.starter.MyAutoConfiguration
2.7+版本变化
Spring Boot 2.7+推荐使用新文件路径:
Java
# 新路径:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.starter.MyAutoConfiguration
每行一个配置类,无需key-value格式。
text
// 新旧方式并存,优先使用新方式
// SpringFactoriesLoader仍兼容spring.factories
要点总结
- SpringFactoriesLoader扫描所有META-INF/spring.factories
- 文件格式为Properties,key为接口全限定名
- 自动配置类通过EnableAutoConfiguration作为key注册
- 加载后经过去重、排除、过滤三步处理
- Spring Boot 2.7+支持新的imports文件格式
📝 发现内容有误?点击此处直接编辑