SpringBoot3 spring.factories自动配置功能不生效的解决
作者:小时候的阳光
场景说明
原来的SpringBoot 自动配置功能如下,主要是创建spring.factories 文件,在里面写入你要自动配置的类全路径。
文件内容如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.bigshow.starter.sse.config.SseAutoConfigure
其中 SseAutoConfigure
就是你要自动化配置的类:
/** * SSE服务端 核心配置类 * * @author BigShow */ @Configuration @ConditionalOnProperty(prefix = "bigshow.sse", value = "enable", havingValue = "true") @EnableConfigurationProperties({SseProperties.class}) public class SseAutoConfigure implements InitializingBean { @Lazy @Resource private ApplicationContext applicationContext; @Bean @ConditionalOnMissingBean SseServer sseServer() { return new SseServer(); } @Bean @ConditionalOnMissingBean public SseBusinessService sseBusinessService() { return new DefaultSseBusinessServiceImpl(); } }
该项目打包 mvn clean install
或者 mvn deploy
发布到maven仓库中去,
其他应用项目直接引入然后在application.yml文件中配置一下即可使用此功能。
<dependency> <groupId>com.bigshow</groupId> <artifactId>sse-spring-boot-starter</artifactId> <version>1.0</version> </dependency>
bigshow: sse: enable: true
但是!从SpringBoot3开始,这样 spring.factories 自动配置功能不生效了。
原因是:官方做出了改变!
原因说明
Spring Boot 3采用了基于META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件的自动配置加载策略,替代了过去的spring.factories
方式
注意:文件名字就是 “org.springframework.boot.autoconfigure.AutoConfiguration.imports”
这个文件里面的内容就是你要配置类的全路径名称即可:
com.example.autoconfig.MyAutoConfiguration1 com.example.autoconfig.MyAutoConfiguration2 com.example.autoconfig.MyAutoConfiguration3 ...
看到这里不禁要问:这和之前的有什么区别 ,感觉就是配置文件名称不一样了 ? !
从表面上看,确实是这样,但是这为未来提供了很大的意义:
原来的 spring.factories
文件里面可以做很多其他的事情,它是一个 多功能的配置文件,采用键值对形式,内部可以声明多种类型的自动加载内容,不只是自动配置类,还包括:
- 监听器(ApplicationListener)
- 环境后置处理器(EnvironmentPostProcessor)
- ApplicationContextInitializer
- FactoryBean 等等
所以确实,spring.factories
文件长期承担了很多职责,Spring Boot3
通过拆分专用文件来让自动配置更清晰规范,也更适合未来演进,
Spring Boot 3 对 spring.factories 中的自动配置部分做了拆分,但 其他功能和扩展点并没有全部抛弃 spring.factories,而是逐步迁移或沿用不同的新机制。
功能类型 | 以前在 spring.factories 里声明 | Spring Boot 3 处理方式(现状) |
---|---|---|
自动配置类(EnableAutoConfiguration) | 在 spring.factories 的 key: org.springframework.boot.autoconfigure.EnableAutoConfiguration | 拆分到 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中声明类全名 |
ApplicationListener | spring.factories的org.springframework.context.ApplicationListener | 依然使用 spring.factories 方式声明,暂时未拆分,未来可能转为模块化机制 |
EnvironmentPostProcessor | spring.factories的org.springframework.boot.env.EnvironmentPostProcessor | 依然通过 spring.factories 声明继续使用 |
ApplicationContextInitializer | spring.factories的org.springframework.context.ApplicationContextInitializer | 目前依然使用 spring.factories |
FactoryBean及其他扩展类 | spring.factories声明 | 大多数依然沿用 spring.factories,具体视扩展功能而定 |
简单总结过去和现在的配置文件方式对比:
方面 | 以前的 spring.factories | 现在的 AutoConfiguration.imports |
---|---|---|
作用范围 | 多种扩展点都在里面声明 | 只声明自动配置类 |
文件结构 | key-value 配置格式 | 纯粹类名列表,每行一个全限定类名 |
维护复杂度 | 可能集中且复杂 | 简单、专一,后续更易扩展 |
兼容性 | 老版本Spring Boot依赖 | Spring Boot 3及以后版本推荐 |
未来趋势和新机制
- Spring 团队计划逐步拆解 spring.factories 的过度职责,将不同的扩展分别拆分到更明确、可维护的专用文件或基于 Java 模块系统(JPMS)的机制中。
- 部分机制将使用 spring.autoconfigure 专用资源文件,其他高级扩展会结合 SPI(ServiceLoader机制)、spring/org/springframework/boot 下的专用目录,或者全新注解驱动方式实现。
- 但目前绝大多数非自动配置的扩展仍旧通过 spring.factories 管理。
如何迁移老的starter
原自定义的starter工程:
删除META-INF/spring.factories文件或者停止使用它。
在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中添加你的自动配置类路径,例如:
com.bigshow.starter.sse.config.SseAutoConfigure
自动配置类里使用@AutoConfiguration
替换原来@Configuration
和 (Spring Boot 3 官方推荐使用@AutoConfiguration替代以前的@Configuration + @ConditionalOn等组合注解)
@AutoConfiguration @ConditionalOnProperty(prefix = "bigshow.sse", value = "enable", havingValue = "true") @EnableConfigurationProperties({SseProperties.class}) public class SseAutoConfigure implements InitializingBean { ... }
这里简单说明下:@Configuration 换成 @AutoConfiguration 好处
- 明确标识自动配置类身份
- 增强编译期和IDE的支持
- 更精准的自动配置加载机制
- 未来扩展和模块化支持更友好
- 避免潜在的类路径扫描冲突
- 结合条件注解效果更可靠
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。