使用@Retryable和@Recover的方法不会使用@SpringBootTest调用@Recover方法

时间:2018-06-08 17:39:49

标签: java spring spring-boot spring-retry

我正在使用@Retryable方法查看SpringBoot应用程序中的一些代码,其他方法标记为@Recover。当我们运行整个应用程序并进行我们知道的远程调用将失败时,它会正确调用@Recover方法。

但是,当我们使用类似条件的@SpringBootTest运行测试时,它从不调用@Recover方法。我们有很多调试输出。我确实注意到我们正在运行的服务器(不是测试用例)中的一种情况,我们看到了以下内容:

Exception ExhaustedRetryException: Cannot locate recovery method;

我在测试用例的调试输出中寻找它,但我没有找到它。

测试类具有以下注释:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = { Application.class })

我们的Application类具有以下注释:

@SpringBootApplication
@PropertySource("classpath:application.properties")
@ComponentScan(basePackages = "com")
@EnableAsync
@EnableRetry
@EnableCaching
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
        HazelcastAutoConfiguration.class, CacheAutoConfiguration.class, CassandraAutoConfiguration.class,
        CassandraDataAutoConfiguration.class, CassandraRepositoriesAutoConfiguration.class })

Spring基础架构中是否有一些特定的方法可以逐步查看为什么它没有找到,或者甚至找不到恢复方法?

更新

所以我意识到当我在debug中执行测试时,我没有在stacktrace中的任何地方看到Spring RetryTemplate。是不是控制从Retryable方法到Recover方法的流程?这似乎指出了我在测试类中缺少的一些设置,或者可能表明这根本无法在测试类中完成(我希望这不是真的)。​​

更新

好的,我设法解决了这个问题。发生这种情况是因为我忽略了从Spring注入bean,我只是手动创建了一个。这意味着它没有连线使用RetryTemplate,因此它从未试图找到@Recover方法。一旦我将“@Autowired”添加到测试类中的实例变量中,它就会遇到这个问题(然后用下一个问题打我,但我理解了这个问题。)

1 个答案:

答案 0 :(得分:0)

该异常来自RecoverAnnotationRecoveryHandler,因此看起来重试是可操作的,但由于某种原因,它无法找到恢复方法。

Method method = findClosestMatch(cause.getClass());
if (method == null) {
    throw new ExhaustedRetryException("Cannot locate recovery method", cause);
}

因此,它正在寻找一种匹配异常的方法。

findClosestMatch只是扫描已发现的方法,找到参数匹配的方法。

我建议您使用调试器并在其中放置断点以找出无法找到匹配项的原因。