GuiceとSpringがメソッドインターセプトのフードの下でAOP Allianceを使用していることを確認し、AOP Allianceが特定の例外をインターセプトして処理する方法を理解しようとしているため、同じコードを何度も書き続ける必要はありません。すべてのcatch
ブロック内で繰り返します。
しかし、プレイを確認した後、AOPアライアンスは、スローされたThrowable
sをインターセプトして、ハンドラー/インターセプターがいくつかのこと(例外のログなど)を実行できるようにして、- 例外をさらに伝播するかどうか、または例外をスローした行の次の行に回復するかどうかを決定します:
_HerpDerp hd = null;
if(hd == null)
throw new RuntimeException("Herpyl derp!");
Manny.pacquiao();
_
RuntimeException
をインターセプトし、ビジネスロジックを使用して伝播を続けるか、Manny.pacquioa()
呼び出しで回復するかを決定するAOP例外処理メカニズムを探しています。
ありがとう!
Spring AOPで例外をキャッチできますが、それが純粋なJavaフレームワークの要件に一致するかどうかはわかりません。
Springでは、次のような単純なAOPインターセプターを作成できます。
@Aspect
public class ErrorInterceptor{
@AfterThrowing(pointcut = "execution(* com.mycompany.package..* (..))", throwing = "ex")
public void errorInterceptor(WidgetException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Error Message Interceptor started");
}
// DO SOMETHING HERE WITH EX
logger.debug( ex.getCause().getMessage());
if (logger.isDebugEnabled()) {
logger.debug("Error Message Interceptor finished.");
}
}
}
ただし、呼び出し元のメソッドに戻ったり、次の行で処理を続行したりする方法はありません。ただし、ここで例外を処理する場合、自分で再スローしない限り、チェーンが浮上することはありません。
これが存在しない理由があります。そもそもtry/catchブロックを書いたかのように、コードのブロック構造を書き直す必要があります。これは、私には、変数のスコープやその他のもので潜在的に大混乱を演じているようです。あなたはバイトコードを次のコードのようなものに書き換えるようにAOPに求めています、そしてそれはかなりの書き換えです。
HerpDerp hd = null;
try {
if(hd == null)
throw new RuntimeException("Herpyl derp!");
} catch(RuntimeException e) {
if (someConditionIsMet) {
throw e;
}
}
Manny.pacquiao();
@ 4herpsand7derpsagoあなたがしようとしているのが、AOPを使用してスローされた例外をキャッチし、それを処理するためのさまざまなタスクを実行してから、例外が最初にスローされたコードに戻ってくる場合、AOPの概念を理解していないと思います。
コードで指摘するように
_HerpDerp hd = null;
if(hd == null)
throw new RuntimeException("Herpyl derp!");
Manny.pacquiao();
_
AOPがRuntimeException
をキャッチし、それを処理するためにいくつかの処理を実行してManny.pacquiao();
に戻ってくる場合、答えはできないです。その理由は、RuntimeException
がAOPによってスローおよびキャッチされたとき、スタックはすでにAOPコードにあるためです。 Many.pacquiao();
を実行するために戻ることはできません。 Many.pacquiao();
の実行を継続する場合の唯一の方法は、次のように_try-finally
_ブロックを使用することです
_HerpDerp hd = null;
try {
if(hd == null)
throw new RuntimeException("Herpyl derp!");
} finally {
Manny.pacquiao();
}
_
そうして初めてMany.pacquiao()
が実行されますが、AOPがRuntimeException
をキャッチする前に
AspectJでキャッチされない例外を「キャッチ」するには、次のアスペクトを使用できます。
pointcut uncaughtExceptionScope() :
(execution(* com.mycompany.myrootpackage..Main.main(..))
|| execution(* Java.util.concurrent.Callable+.call())
|| execution(* Java.lang.Runnable+.run())
));
after() throwing(Throwable t) : uncaughtExceptionScope() && !cflow(adviceexecution()) {
handleException(thisJoinPoint, t);
}
protected void handleException(JoinPoint jp, Throwable t)
{
// handle exception here
}
実行ポイントに「戻る」ことはできないと思います。