[英]Spring issue with @PostConstruct and @PreDestroy
I have a Spring application that I am trying to test with EmbededRedis.我有一个 Spring 应用程序,我正在尝试使用 EmbededRedis 进行测试。 So I created a component like below to Initialize and kill redis after test.
所以我创建了一个像下面这样的组件来初始化并在测试后杀死 redis。
@Component
public class EmbededRedis {
@Value("${spring.redis.port}")
private int redisPort;
private RedisServer redisServer;
@PostConstruct
public void startRedis() throws IOException {
redisServer = new RedisServer(redisPort);
redisServer.start();
}
@PreDestroy
public void stopRedis() {
redisServer.stop();
}
}
But now I am facing a weird issue.但现在我面临一个奇怪的问题。 Because spring caches the context, PreDestroy doesnt get called everytime after my test is executed, but for some reason, @PostConstruct gets called, and EmbededRedis tries to start the running redis server again and again, which is creatimg issues in the execution.
因为 spring 缓存了上下文,所以在我的测试执行后每次都不会调用 PreDestroy,但是由于某种原因,@PostConstruct 被调用,并且 EmbededRedis 试图一次又一次地启动正在运行的 redis 服务器,这是执行过程中的问题。
Is there a way to handle this situation by any mean?有没有办法以任何方式处理这种情况?
Update This is how I am primarily defining my tests.更新这就是我主要定义我的测试的方式。
@SpringBootTest(classes = {SpringApplication.class})
@ActiveProfiles("test")
public class RedisApplicationTest {
Ditch the class and write an @Configuration
class which exposed RedisServer
as a bean.抛弃 class 并编写一个
@Configuration
class 将RedisServer
暴露为一个 bean。
@Configuration
public void EmbeddedRedisConfiguration {
@Bean(initMethod="start", destroyMethod="stop")
public RedisServer embeddedRedisServer(@Value("${spring.redis.port}") int port) {
return new RedisServer(port);
}
}
So I debuged the ContextInitialization as suggested by @M.所以我按照@M 的建议调试了 ContextInitialization。 Deinum.
迪南。
For me, the porblem was, Our application was mocking different classes in order to mix mocking with Spring context.对我来说,问题是,我们的应用程序是 mocking 不同的类,以便将 mocking 与 Spring 上下文混合。 Now, when you use mocks,
MockitoContextInitializer
also becomes part of your cache key , which results in cache miss.现在,当您使用模拟时,
MockitoContextInitializer
也会成为您缓存键的一部分,这会导致缓存未命中。 Reason is, The classes under mock are obviously different for different test classes.原因是,对于不同的测试类,mock 下的类明显不同。
Looking at the situation, I preferred to go ahead with @DirtiesContext
to invalidate the contest after the test is done, so that I can reinitialize the context later on for different test.看情况,我更喜欢 go 在测试完成后使用
@DirtiesContext
使比赛无效,以便稍后我可以重新初始化上下文以进行不同的测试。
Note @DirtiesContext
is in a way recommended to be avoided as it slows down your tests.注意
@DirtiesContext
建议避免使用,因为它会减慢测试速度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.