如何阻止Spring测试结束后调用远程WireMock实例的shutdown方法?
解决Spring自动调用WireMock客户端shutdown的问题
Spring容器销毁Bean时,会自动识别实现了AutoCloseable或Closeable接口的Bean,并调用其close()方法。而WireMock客户端的close()方法内部会触发对远程WireMock服务器的shutdown请求——这就是问题的核心:即便WireMock.shutdown()没有标注@PreDestroy,但close()方法被Spring自动调用了。
解决方案
1. 配置Bean时禁用默认销毁方法
直接在@Bean注解中指定destroyMethod = "",告诉Spring不要使用默认的销毁逻辑(也就是不要调用close()方法):
@Configuration public class WireMockConfiguration { @Bean(destroyMethod = "") public WireMock wireMock() { return new WireMock("my-pyroxy.corp", 8080); } }
这是最简单直接的方案,仅需修改一行配置即可生效。
2. 包装WireMock客户端,隔离Closeable接口
编写一个包装类,只暴露测试需要的WireMock方法,不实现Closeable接口,让Spring管理这个包装类而非原生WireMock实例:
// 自定义包装类 public class WireMockClientWrapper { private final WireMock wireMock; public WireMockClientWrapper(String host, int port) { this.wireMock = new WireMock(host, port); } // 仅暴露测试用到的方法,例如: public void stubFor(RequestDefinitionBuilder requestBuilder) { wireMock.stubFor(requestBuilder); } public void verify(RequestPatternBuilder requestPatternBuilder) { wireMock.verify(requestPatternBuilder); } // 不要暴露close方法或原生WireMock实例 }
然后修改配置类返回包装类:
@Configuration public class WireMockConfiguration { @Bean public WireMockClientWrapper wireMockClient() { return new WireMockClientWrapper("my-pyroxy.corp", 8080); } }
这种方式完全隔离了Spring与原生WireMock客户端的销毁逻辑,适合需要严格控制Bean行为的场景。
3. 通过BeanPostProcessor修改销毁方法
注册一个BeanPostProcessor,动态修改WireMock Bean的销毁方法配置,使其不触发close():
@Configuration public class WireMockConfiguration { @Bean public WireMock wireMock() { return new WireMock("my-pyroxy.corp", 8080); } @Bean public BeanPostProcessor wireMockDestroyMethodDisabler() { return new BeanPostProcessor() { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WireMock) { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) ApplicationContextHolder.getApplicationContext(); BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); beanDef.setDestroyMethodName(null); } return bean; } }; } }
注:需要自行实现ApplicationContextHolder来获取Spring容器实例,这种方式相对复杂,仅推荐在无法修改原有Bean定义的场景下使用。
内容的提问来源于stack exchange,提问作者Ubeogesh
相关产品推荐
相关产品推荐

