春の再試行を試みていますが、奇妙な問題に直面しています。Rest Controller内のメソッドで再試行アノテーションを使用すると、再試行が機能しません。しかし、そのメソッドを別のサービスクラスに移動すると、機能します。次のコードは機能しません。
@RestController
public class HelloController {
@RequestMapping(value = "/hello")
public String hello() {
return getInfo();
}
@Retryable(RuntimeException.class)
public String getInfo() {
Random random = new Random();
int r = random.nextInt(2);
if (r == 1) {
throw new RuntimeException();
} else {
return "Success";
}
}
}
しかし、以下はそうです:
@RestController
public class HelloController {
@Autowired
private SomeService service;
@RequestMapping(value = "/hello")
public String hello() {
String result = service.getInfo();
return result;
}
}
@Service
public class SomeService {
@Retryable(RuntimeException.class)
public String getInfo() {
Random random = new Random();
int r = random.nextInt(2);
if (r == 1) {
throw new RuntimeException();
} else {
return "Success";
}
}
}
私の質問は@Retryable
、コントローラーで使用したときにが機能しないのはなぜですか?
表示されている問題は、getInfo()
メソッドの呼び出し方法が原因です。
最初の例ではgetInfo()
、同じSpringマネージドBean内から呼び出しています。2番目の例ではgetInfo()
、別のSpringマネージドBeanから呼び出しています。この区別は微妙ですが、非常に重要であり、問題の原因である可能性が非常に高くなります。
@Retryable
アノテーションを使用すると、Springは元のBeanの周りにプロキシを作成して、特別な状況で特別な処理を実行できるようにします。この特定のケースでは、SpringはAdviceを適用して、実際のメソッドへの呼び出しを委任し、RuntimeException
スローする可能性のあるをキャッチして、@Retryable
アノテーションの構成に従ってメソッドの呼び出しを再試行します。
あなたの場合、このプロキシが重要である理由は、外部の発信者だけがプロキシのアドバイスを見るからです。Beanは、プロキシされていることを認識しておらず、そのメソッドが(プロキシのアドバイスによって)呼び出されていることだけを知っています。Beanがそれ自体でメソッドを呼び出す場合、それ以上のプロキシは含まれません。そのため、再試行は実際には発生しません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加