使用@EnableAutoConfiguration时自定义Spring Boot Starter无法读取application.properties
这个问题的核心在于**@EnableAutoConfiguration本身并不负责加载Spring Boot的配置文件(比如application.properties)**,它只是Spring Boot自动配置机制的一部分,而完整的配置文件加载是Spring Boot应用上下文初始化流程的核心环节——这正是@SpringBootTest帮你自动完成的事情。
具体原因拆解:
@EnableAutoConfiguration的职责边界:这个注解的作用仅仅是告诉Spring:"去加载所有
META-INF/spring.factories里定义的自动配置类"。它没有触发Spring Boot特有的环境初始化逻辑,比如从classpath、环境变量、命令行参数等来源加载配置属性。当你在测试类里只使用@EnableAutoConfiguration时,Spring容器只会使用默认的空环境,根本不会主动去读取你的application.properties。@SpringBootTest的完整能力:这个测试注解是专门为Spring Boot应用测试设计的,它会启动一个完整的Spring Boot应用上下文。这意味着它会自动执行以下关键操作:
- 加载classpath下的
application.properties(以及application.yml、Profile特定的配置文件) - 处理配置属性绑定逻辑(比如你定义的
@ConfigurationProperties类) - 触发所有自动配置流程
- 初始化完整的Spring环境
- 加载classpath下的
回到你的测试场景:当你只用@EnableAutoConfiguration时,CustomStarterProperties里的message属性根本没被赋值(因为application.properties没被加载),所以customStarterMessage这个Bean返回的是null,测试自然失败。而用@SpringBootTest时,配置文件被正确加载,属性绑定生效,Bean也能拿到预期的值。
如果你不想用@SpringBootTest,怎么让@EnableAutoConfiguration读取配置?
如果想在测试中保留@EnableAutoConfiguration同时加载application.properties,可以通过以下两种方式实现:
- 添加@PropertySource注解,手动指定配置文件:
@RunWith(SpringRunner.class) @EnableAutoConfiguration @PropertySource("classpath:application.properties") public class TotoTest { @Autowired String customStarterMessage; @Test public void loadContext() { assertThat(customStarterMessage).isNotNull(); } }
- 用@SpringBootApplication替代@EnableAutoConfiguration:
@SpringBootApplication本身就包含了@EnableAutoConfiguration,同时还会触发Spring Boot的环境初始化流程,自动加载配置文件:
@RunWith(SpringRunner.class) @SpringBootApplication public class TotoTest { @Autowired String customStarterMessage; @Test public void loadContext() { assertThat(customStarterMessage).isNotNull(); } }
不过要注意:如果你的测试类和主应用类不在同一个包下,可能需要调整@ComponentScan的扫描范围,但对于自定义Starter的测试场景来说,通常不需要额外处理。
内容的提问来源于stack exchange,提问作者matdan

