2016-07-03 6 views
1

AnnotationConfigApplicationContextを使用して、春のフレームワークベースのアプリケーションを作成しました。@PostConstructと@Retryableを一緒に使用できないのはなぜですか?

1つのBeanには、外部サービスへの接続を作成するinitメソッドがあります。これは、動作するbeanが開始されると自動的に実行されるように@PostConstructと注釈することができます。

この接続を作成する際に例外を処理するには、例外がキャッチされた場合にinitメソッドが最大5回再試行するようにします。 @PostConstruct@Retryableの両方でメソッドに注釈を付けると、例外が1回スローされ、プログラムが終了することがわかります。@Retryableは効果がありません。

私は@Configurationと一緒に正しく構成クラスに@EnableRetryを使用しました。このメソッドがBeanがインスタンス化された後に呼び出された場合、再試行可能と注釈された同じBeanに別のメソッドBを作成しました。メソッドが再試行されたことがわかります/例外がスローされたときに期待通りに動作します。

なぜこれがうまくいかないのか何かが関連しているか、spring-retry要素が接続される前にpostconstructが起こっていると思いますか?

実際には、例外を処理し、注釈を使用して再試行可能な初期化メソッドを持つ方が良いですか?メソッドでプログラムで試してみるのではなく、

編集:外部サービスへの接続の作成を@Postconstructで行うべきではないと私は同意します。これは、再試行が失敗し、有害な影響を及ぼす可能性がある場合、コンテキスト全体を初期化から停止させる可能性があります。

しかし、これは、Spring Frameworkのどの部分がこれらの2つの注釈を連動させないのかという疑問にはまだ答えていません。

答えて

-1

'@Retryable'は 'spring-retry'によって適用される側面です。これは、春のコンテキストが完全に作成された後にのみ結び付けられます。結局のところ、 '@PostConstruct'注釈付きメソッドが実行されるため、 '@Retryable'は効果がありません。

+0

この投稿はよく分かりますhttps://stackoverflow.com/a/41856170/3309466 –

1

ContextRefreshedEventをリッスンし、このメソッドにリトライロジックを注釈したApplicationListenerを実際に適用することをお勧めします。これらのリスナーは、コンテキストが完全にリフレッシュされ、すべてのBeanが適切に構成され配線されると起動されます。

+0

ポストコンストラクトをEventListener({ContextRefreshedEvent。class})とRetryableを組み合わせると、私が望む動作が得られます。 Contextは、アプリケーションのライフサイクルで複数回リフレッシュできるので、探しているソリューションとは異なる可能性があります。接続を作成するメソッドは、X回の再試行で1回だけ実行する必要があります。 – UserF40

+0

はいコンテキストを複数回リフレッシュすることができますが、リフレッシュするたびにBeanコンテキストでBeanを再作成するため、Beanに関係なく必要な動作が得られます。 – Naros

2

この接続を作成する際に例外を処理するには、例外がキャッチされた場合にinitメソッドが最大5回再試行するようにします。

initメソッドでは、決してリソースに接続しないでください。最初にコンテキストを作成するのを待つ必要があります。

SmartLifecycleを実装してstart()に接続する方がずっと良いです。これにより、外部リソースへの接続を開始する前に、コンテキスト全体が初期化されていることを確認できます。

このように、start()メソッドは、再試行インターセプタによって通知される必要があります。

@Narosが示唆しているように、ContextRefreshedEventは別の方法ですが、決して@PostConstructにそのようなことはしないでください。

関連する問題