3

我创建了一个基于 Spring 框架的应用程序,使用AnnotationConfigApplicationContext.

一个 bean 有一个 init 方法,它创建到外部服务的连接。@PostConstruct一旦启动了工作的bean,就可以对其进行注释以自动运行。

为了在创建此连接时处理任何异常,如果捕获到异常,我希望我的 init 方法最多重试 5 次。当用两者注释方法时@PostConstruct@Retryable我看到异常被抛出一次并且程序退出 - 它似乎@Retryable没有效果。

我已经@EnableRetry在配置类中正确使用了@Configuration. 我在同一个 bean 上创建了另一个方法 B,它被注释为可重试,如果在实例化 bean 之后调用此方法,我可以看到该方法在抛出异常时被重试/按预期运行。

我对为什么这不起作用的想法可能与某些方面有关,或者 postconstruct 发生在 spring-retry 元素附加之前?

实际上有没有更好的方法来拥有一个可以处理异常并可以通过注释重试的初始化方法 - 而不是在方法中以编程方式尝试?

编辑:我现在同意不应通过@Postconstruct. 如果重试失败,这可能会阻止整个上下文初始化,这可能会产生不利影响。

然而,这还没有回答 Spring 框架的哪一部分不让这两个注释一起工作的问题。

4

3 回答 3

3

为了在创建此连接时处理任何异常,如果捕获到异常,我希望我的 init 方法最多重试 5 次。

您永远不应该在 init 方法中连接到资源;您应该等待首先创建上下文。

SmartLifecycle实施和连接要好得多start()。这样,您可以确保在开始连接到外部资源之前已经初始化了整个上下文。

这样,start()重试拦截器应该通知该方法。

正如@Naros 建议的那样,这ContextRefreshedEvent是另一种选择,但你不应该,永远,永远不要在@PostConstruct.

于 2016-07-04T01:44:25.987 回答
2

我建议你实际应用一个ApplicationListener监听 a 的ContextRefreshedEvent方法,并用你的重试逻辑注释这个方法。一旦上下文完全刷新并且所有 bean 都已正确配置和连接,这些侦听器就会被触发。

于 2016-07-03T21:10:59.173 回答
1

'@Retryable' 是'spring-retry' 应用的一个方面。这仅在完全创建弹簧上下文后附加,毕竟“@PostConstruct”注释方法运行,因此“@Retryable”无效。

于 2016-07-07T16:01:21.553 回答