Spring Boot 3.x 为什么要“杀死” spring.factories?

51 阅读4分钟

沉默是金,总会发光

大家好,我是沉默

“启动慢,怪 spring.factories?不支持原生镜像,还是它的锅?”

**-**01-

spring.factories 到底干了啥?

如果说 SpringBoot 自动配置 是魔法,那么 spring.factories 就是那根藏在帽子里的魔杖。

它是一个放在 META-INF/ 下的配置文件,
用于告诉 SpringBoot ——“要启动这些自动配置类!”

// SpringBoot 2.x 自动加载机制org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.example.FooAutoConfiguration,\com.example.BarAutoConfiguration

它基于 Java SPI(服务发现机制) ,让 Spring 能在启动时动态加载各种组件。
听起来很优雅,但随着项目变大,它逐渐成了“性能杀手”。

- 02-

SpringBoot 3.0 为什么要干掉它?

Spring 团队的解释是“为了性能和模块化”,但我们拆开看,原因其实有五层

问题点说明后果
启动性能每次启动都要扫描所有 jar 包里的 spring.factories大项目启动像背锅侠一样慢
模块系统冲突Java 9 引入 JPMS 模块化,spring.factories 与之不兼容无法模块化加载
条件加载能力弱配置静态、全量加载,无法灵活启用或禁用内存浪费
配置分散不同模块各自配置,难统一管理可维护性差
GraalVM 不兼容动态扫描机制无法静态分析无法原生编译

Spring 团队希望:从“运行时动态扫描”→“构建时静态确定”
以更好地拥抱 GraalVM 与云原生时代。

- 03-

新的 imports 机制取而代之

SpringBoot 3.0 引入了一个更“工整”的方案:
每个扩展点都有自己独立的 imports 文件,放在 META-INF/spring/ 下。

对比项SpringBoot 2.xSpringBoot 3.x
注册文件META-INF/spring.factoriesMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
格式key=value 键值对每行一个类名
扫描方式运行时扫描所有 jar构建时静态加载
模块化支持
GraalVM 支持

**
**

新写法示例:

// AutoConfiguration.importscom.example.FooAutoConfigurationcom.example.BarAutoConfiguration

简洁、静态、可模块化
不再“神奇”,但更可控、更现代。

**-****04-**开发者如何迁移?

步骤操作示例
1️⃣找出旧的 spring.factories位于 META-INF/ 下
2️⃣把自动配置类复制到新文件中AutoConfiguration.imports
3️⃣类上用 @AutoConfiguration 替代 @Configuration支持 AOT 编译
4️⃣验证启动日志确保配置被正确加载
5️⃣删除旧文件干净利落
@AutoConfiguration@EnableConfigurationProperties(MyProperties.class)public class MyAutoConfiguration {    @Bean    public MyService myService() {        return new MyService();    }}

**-****05-**总结

性能提升

图片

实际测试:

在一个中型项目中,SpringBoot 3.x 启动平均提速 15%~30%
对 GraalVM 原生镜像支持提升更是质变。

SpringBoot 3.0 背后的 GraalVM

SpringBoot 3.0 的底层变革核心之一就是 支持 GraalVM Native Image
它能让 Java 应用“脱 JVM 运行”,启动速度提升百倍!

为什么 spring.factories 不适配 GraalVM?

限制项原因后果
静态分析限制动态扫描无法在编译时确定无法生成原生镜像
反射依赖GraalVM 需提前声明反射类需手动配置
资源访问差异原生镜像中资源访问机制不同扫描失败

新的 imports 文件能被 AOT 引擎(Ahead-Of-Time Processor)  静态分析,在编译阶段就生成所有元数据。

// Spring AOT 编译时逻辑简化示意List<String> configs = readImportsFiles();generateProxies(configs);generateReflectionConfig(configs);

这就是 SpringBoot 3.0 + GraalVM 的黄金搭档。

什么时候应该迁移?

图片

建议:

  • 新项目 → 直接上 imports

  • 旧项目 → 分阶段迁移(优先迁移自动配置类)

  • 使用 GraalVM → 必迁!

Spring 的“演化之路”

SpringBoot 2.x:魔法时代——“它自动帮我搞定一切”
SpringBoot 3.x:工程时代——“我明确告诉它该搞定什么”

取消 spring.factories 不是倒退,而是一次 从动态魔法到静态工程化的升级

这标志着 SpringBoot 正在全面拥抱 AOT、GraalVM、云原生化 的未来。

当 Spring 不再“神秘”,你才真正理解了它的优雅。

**-****06-**粉丝福利

我这里创建一个程序员成长&副业交流群, 


 和一群志同道合的小伙伴,一起聚焦自身发展, 

可以聊:


技术成长与职业规划,分享路线图、面试经验和效率工具, 




探讨多种副业变现路径,从写作课程到私活接单, 




主题活动、打卡挑战和项目组队,让志同道合的伙伴互帮互助、共同进步。 




如果你对这个特别的群,感兴趣的, 
可以加一下, 微信通过后会拉你入群, 
 但是任何人在群里打任何广告,都会被我T掉。