Spring Boot重写spring-context初始化器时读取配置属性值报错
问题根因
ApplicationContextInitializer 的执行时机远早于Spring的属性注入流程:Spring Boot启动时,初始化器会在应用上下文刚创建、还未完成Bean实例化、属性注入、配置绑定操作的阶段就触发执行,同时你的WireMockInitializer本身也不是被Spring容器托管的普通Bean,@Value注解没有生效机会,因此wmPort字段为null,调用其intValue()时抛出空指针。
解决方案
方案1:直接从上下文环境读取配置(最适配初始化器场景)
直接通过初始化方法入参的ConfigurableApplicationContext获取环境配置,无需使用@Value注解,修改后代码如下:
public class WireMockInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { private WireMockServer wireMockServer; @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { // 直接从上下文环境读取配置,第三个参数为默认值 Integer wmPort = configurableApplicationContext.getEnvironment() .getProperty("wiremock.port", Integer.class, 2222); // 仅测试环境执行逻辑 List<String> activeProfiles = Arrays.asList(configurableApplicationContext.getEnvironment().getActiveProfiles()); if (!activeProfiles.contains("test")) { return; } wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(wmPort)); wireMockServer.start(); configurableApplicationContext.addApplicationListener(applicationEvent -> { if (applicationEvent instanceof ContextClosedEvent) { wireMockServer.stop(); } }); configurableApplicationContext.getBeanFactory() .registerSingleton("wireMockServer", wireMockServer); } }
额外说明:@ActiveProfiles 放在初始化器上不生效,因此上述代码直接增加了profile判断逻辑。
方案2:改用Spring事件监听实现(更符合Spring常规用法)
如果希望使用@Value注入,可以放弃实现ApplicationContextInitializer,改为用Spring托管Bean+事件监听的方式实现,此时属性注入已经完成,不会出现空指针:
@Component @ActiveProfiles({"test"}) public class WireMockHolder { private WireMockServer wireMockServer; @Value("${wiremock.port:2222}") private Integer wmPort; // 上下文刷新完成后触发,此时@Value已经注入完成 @EventListener(ContextRefreshedEvent.class) public void startWireMock() { wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(wmPort)); wireMockServer.start(); } // 上下文关闭时自动停止服务 @EventListener(ContextClosedEvent.class) public void stopWireMock() { if (wireMockServer != null) { wireMockServer.stop(); } } }
内容的提问来源于stack exchange,提问作者Prashanth Sams
相关产品推荐
相关产品推荐

