Spring Boot 3.x 与 Spring Boot 2.x 自动配置实现原理 分析。
🧠 一、Spring Boot 2.x 自动配置原理(基于 spring.factories)
✅ 1. 自动配置入口:@EnableAutoConfiguration
Spring Boot 2.x 的自动配置通过 @EnableAutoConfiguration 注解触发:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
✅ 2. 自动配置类加载机制:SpringFactoriesLoader
Spring Boot 2.x 使用 SpringFactoriesLoader 从 META-INF/spring.factories 文件中加载自动配置类:
public final class SpringFactoriesLoader {
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
ClassLoader classLoaderToUse = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader();
Enumeration<URL> urls = classLoaderToUse.getResources(FACTORIES_RESOURCE_LOCATION); // 即 "META-INF/spring.factories"
List<String> result = new ArrayList<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames = properties.getProperty(factoryTypeName);
if (factoryClassNames != null) {
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
}
return result;
}
}
✅ 3. 自动配置类的筛选机制
Spring Boot 会加载所有 spring.factories 中的自动配置类,并通过 @Conditional 系列注解(如 @ConditionalOnClass、@ConditionalOnMissingBean)筛选是否生效。
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
List<String> configurations = getCandidateConfigurations(annotationMetadata, null);
configurations = removeDuplicates(configurations);
Set<String> autoConfigurationGroup = getAutoConfigurationGroup(annotationMetadata, configurations);
return StringUtils.toStringArray(autoConfigurationGroup);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
// 通过 SpringFactoriesLoader 加载 spring.factories 中的自动配置类
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories");
return configurations;
}
}
✅ 4. spring.factories 示例
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyAutoConfiguration
✅ 5. 自动配置类示例
@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean
public class MyAutoConfiguration {
@Bean
public MyService myService() {
return new MyService();
}
}
🔄 二、Spring Boot 3.x 自动配置原理(基于 AutoConfiguration.imports)
✅ 1. 移除 spring.factories,使用 AutoConfiguration.imports
Spring Boot 3.x 不再依赖 spring.factories,而是使用新的配置方式 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。
✅ 示例文件路径:
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
✅ 文件内容(每行一个自动配置类):
com.example.autoconfig.MyAutoConfiguration
✅ 2. 自动配置类加载机制:AutoConfigurationImportSelector 改进
Spring Boot 3.x 中,AutoConfigurationImportSelector 内部逻辑发生变化,改为直接读取 AutoConfiguration.imports 文件。
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
List<String> configurations = getCandidateConfigurations(annotationMetadata, null);
configurations = removeDuplicates(configurations);
Set<String> autoConfigurationGroup = getAutoConfigurationGroup(annotationMetadata, configurations);
return StringUtils.toStringArray(autoConfigurationGroup);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = new ArrayList<>();
try {
// 新版:直接读取 AutoConfiguration.imports 文件
Enumeration<URL> urls = getClass().getClassLoader().getResources("META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports");
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = new Properties();
properties.load(url.openStream());
properties.forEach((key, value) -> configurations.add((String) key));
}
} catch (IOException ex) {
throw new IllegalStateException("Failed to load auto-configuration imports", ex);
}
return configurations;
}
}
✅ 3. 条件注解机制保持不变
Spring Boot 3.x 依然使用 @Conditional 系列注解进行条件装配:
@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean
public class MyAutoConfiguration {
@Bean
public MyService myService() {
return new MyService();
}
}
✅ 4. 支持 Java 17 的新特性(如 getDeclaredConstructors())
Spring Boot 3.x 要求使用 JDK 17 或更高版本,因此内部反射调用方式有所变化:
// Spring Boot 2.x(JDK 8 兼容)
Method method = clazz.getDeclaredMethod("someMethod");
// Spring Boot 3.x(JDK 17+)
Constructor<?> constructor = clazz.getDeclaredConstructors()[0];
📦 三、Spring Boot 3.x 自动配置的完整流程
✅ 1. 启动类:@SpringBootApplication
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
✅ 2. @SpringBootApplication 的作用
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
@EnableAutoConfiguration:触发自动配置@ComponentScan:扫描组件@SpringBootConfiguration:标记为配置类
✅ 3. @EnableAutoConfiguration 的实现
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
@Import(AutoConfigurationImportSelector.class):导入自动配置选择器
✅ 4. AutoConfigurationImportSelector 的改进(Spring Boot 3.x)
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
List<String> configurations = getCandidateConfigurations(annotationMetadata, null);
configurations = removeDuplicates(configurations);
Set<String> autoConfigurationGroup = getAutoConfigurationGroup(annotationMetadata, configurations);
return StringUtils.toStringArray(autoConfigurationGroup);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = new ArrayList<>();
try {
// 新版:读取 AutoConfiguration.imports 文件
Enumeration<URL> urls = getClass().getClassLoader().getResources("META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports");
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = new Properties();
properties.load(url.openStream());
properties.forEach((key, value) -> configurations.add((String) key));
}
} catch (IOException ex) {
throw new IllegalStateException("Failed to load auto-configuration imports", ex);
}
return configurations;
}
}
✅ 5. AutoConfiguration.imports 文件格式(Spring Boot 3.x)
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.autoconfig.MyAutoConfiguration
🧱 四、Spring Boot 2.x 与 3.x 自动配置的核心差异
| 特性 | Spring Boot 2.x | Spring Boot 3.x |
|---|---|---|
| 自动配置文件 | META-INF/spring.factories | META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |
| 配置加载方式 | SpringFactoriesLoader | Properties.load() 直接读取 |
| 支持的 JDK 版本 | JDK 8 ~ 17(兼容旧版本) | JDK 17+(不兼容 JDK 8) |
| 自动配置类加载方式 | 通过 SpringFactoriesLoader 加载 | 通过 Properties 文件直接读取 |
| 性能优化 | 无显著优化 | 避免多次加载 spring.factories,提升启动速度 |
| 模块化支持 | 不支持 JPMS(Java Platform Module System) | 支持 JPMS,兼容模块化项目 |
| 反射 API 使用 | 使用 getDeclaredMethod() | 使用 getDeclaredConstructors()(适配 JDK 17) |
🔄 五、Spring Boot 3.x 自动配置的源码执行流程(简化版)
@SpringBootApplication
└── @EnableAutoConfiguration
└── @Import(AutoConfigurationImportSelector.class)
└── AutoConfigurationImportSelector.selectImports()
└── getCandidateConfigurations()
└── 读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件
└── 加载自动配置类(如 MyAutoConfiguration)
└── 过滤重复配置
└── 按条件筛选(@ConditionalOnClass、@ConditionalOnMissingBean 筃
└── 注册为 BeanDefinition 并注册到容器
🧩 六、Spring Boot 3.x 自动配置的源码关键类
| 类名 | 作用 |
|---|---|
AutoConfigurationImportSelector | Spring Boot 自动配置的核心类,负责加载自动配置类 |
AutoConfiguration.imports | Spring Boot 3.x 的自动配置类配置文件 |
SpringFactoriesLoader | Spring Boot 2.x 使用的自动配置类加载器 |
AutoConfigurationGroup | 负责按条件筛选自动配置类 |
ConditionEvaluator | 评估 @Conditional 注解是否满足条件 |
🧱 七、Spring Boot 3.x 自动配置的性能优化
✅ 1. 避免重复加载 spring.factories
Spring Boot 3.x 使用 AutoConfiguration.imports 替代 spring.factories,避免了多个 spring.factories 文件的合并和去重操作,提升加载效率。
✅ 2. 支持模块化项目(JPMS)
Spring Boot 3.x 完全支持 Java 9+ 的模块化系统(JPMS),自动配置类可以在模块中声明,无需手动配置。
✅ 3. JDK 17 兼容性优化
Spring Boot 3.x 使用 JDK 17 的新特性,如 getDeclaredConstructors() 替代 getDeclaredMethods(),提高反射性能。
📦 八、Spring Boot 3.x 自动配置迁移指南
✅ 1. 从 Spring Boot 2.x 迁移到 3.x
步骤 1:修改自动配置类的注册方式
Spring Boot 2.x:
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyAutoConfiguration
Spring Boot 3.x:
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.autoconfig.MyAutoConfiguration
步骤 2:更新依赖版本
确保所有依赖库已升级到支持 Spring Boot 3.x 的版本(如 Spring Boot 3.0+、Spring Framework 6.0+、Jakarta EE 9+)。
步骤 3:适配 JDK 17+
- 使用
getDeclaredConstructors()替代getDeclaredMethods() - 替换
javax.*为jakarta.* - 使用新的模块化方式构建项目(如
module-info.java)
步骤 4:测试自动配置行为
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Application.class, args);
MyService service = context.getBean(MyService.class);
service.doSomething(); // 验证自动配置是否生效
}
}
🧪 九、完整示例:Spring Boot 3.x 自动配置实现
1. 自动配置类定义
@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean
public class MyAutoConfiguration {
@Bean
public MyService myService() {
return new MyService();
}
}
2. 配置文件(Spring Boot 3.x)
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.autoconfig.MyAutoConfiguration
3. 使用自动配置类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Application.class, args);
MyService service = context.getBean(MyService.class);
service.doSomething(); // 自动配置生效
}
}
✅ 十、总结
| 特性 | Spring Boot 2.x | Spring Boot 3.x |
|---|---|---|
| 自动配置文件 | spring.factories | AutoConfiguration.imports |
| 自动配置类加载方式 | SpringFactoriesLoader | Properties.load() 直接读取 |
| JDK 支持 | JDK 8 ~ 17 | JDK 17+ |
| 模块化支持 | 不支持 JPMS | 支持 JPMS |
| 反射 API 改进 | 使用 getDeclaredMethod() | 使用 getDeclaredConstructors() |
| 性能优化 | 无显著优化 | 避免多次加载 spring.factories |
| 条件注解机制 | 保持一致 | 保持一致 |
🧩 十一、扩展
-
Spring Boot 3.x 自动配置的源码路径:
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectororg.springframework.boot.autoconfigure.AutoConfigurationGroup
-
Spring Boot 3.x 的官方迁移指南:
-
Spring Boot 3.x 的模块化支持:
- 支持 Java 9+ 模块化项目,自动配置类可以定义在模块中
-
Spring Boot 3.x 与 Jakarta EE 9+ 的兼容性:
- 所有
javax.*包名替换为jakarta.*
- 所有

1798

被折叠的 条评论
为什么被折叠?



