简体   繁体   English

Spring 问题与@PostConstruct 和@PreDestroy

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM