23

GuiceとSpringはメソッドインターセプトの内部でAOPAllianceを使用していることがわかります。私は、AOP Allianceに特定の例外をインターセプトして処理させる方法を模索しているので、同じコードを書き続ける必要はありません。すべてのcatchブロック内でもう一度繰り返します。

しかし、プレイを確認した後、AOP AllianceはThrowable、ハンドラー/インターセプターがいくつかのこと(例外のログ記録など)を実行して伝播するかどうかを判断できるように、スローされたをインターセプトする方法を提供していないようです。例外をさらに進めるか、例外をスローした行の次の行に戻るだけです

HerpDerp hd = null;

if(hd == null)
    throw new RuntimeException("Herpyl derp!");

Manny.pacquiao();

RuntimeExceptionをインターセプトし、ビジネスロジックを使用して、それを伝播し続けるか、呼び出しで回復するかを決定するAOP例外処理メカニズムを探していManny.pacquioa()ます。

  • Javaでこれを行うことが不可能な場合は、お知らせください
  • Javaでこれを実行できるかどうかに関係なく、AOP Allianceでスローされた例外をインターセプトする方法はありますか、それとも別の場所に移動する必要がありますか。そして、私がどこかに行かなければならない場合、どこに?AspectJ?

ありがとう!

4

4 に答える 4

40

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.");
    }
}
}

ただし、呼び出し元のメソッドに戻ったり、次の行で処理を続行したりする方法はありません。ただし、ここで例外を処理すると、自分で再スローしない限り、チェーンがバブルアップすることはありません。

于 2012-06-11T15:16:48.380 に答える
4

これが存在しないのには理由があります。そもそもtry/catchブロックを書いたかのように、コードのブロック構造を書き直す必要があります。これは、私には、可変スコープやその他のもので大混乱を引き起こす可能性があるように思われます。あなたはAOPにバイトコードを次のコードのようなものに書き直すように頼んでいます、そしてそれはかなり書き直しです。

HerpDerp hd = null;

try {
    if(hd == null)
        throw new RuntimeException("Herpyl derp!");
} catch(RuntimeException e) {
   if (someConditionIsMet) {
       throw e;
   }
}

Manny.pacquiao();
于 2012-06-11T15:36:08.450 に答える
2

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
}

実行ポイントに「戻る」ことはできないと思います。

于 2012-06-08T12:04:25.103 に答える
2

@ 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

于 2012-06-14T02:57:44.447 に答える