Spring AOP とは対照的に、完全な AspectJ を避けたいことはわかっています。(ところで、なぜ多くの人がそれを恐れているのだろうかhandler()
. ただし、制限が 1 つあります。 orbefore()
ではなく、アドバイスでのみ機能します。これは、コンパイラの制限によるものです。例外ハンドラーの JVM バイト コードを見ると、ハンドラー ブロックの終了を検出する方法がないことがわかります。とにかく、コンセプトは元の質問に関連しているので、ここでそれがどのように行われるかを示したいと思います. 小さなドライバー アプリケーションと非常に単純なアスペクトを作成しました。after()
around()
import java.util.Random;
import javax.naming.AuthenticationException;
public class Application {
public static void main(String[] args) {
Application app = new Application();
System.out.println(app.foo(1, "two", 3d));
System.out.println(app.bar("one", 2d, 3));
System.out.println(app.zot(1d, 2, "three"));
}
public String foo(int i, String string, double d) {
try {
if (new Random().nextBoolean())
throw new AuthenticationException("wrong password");
}
catch (AuthenticationException e) {
return "return value from catch block";
}
return "normal return value";
}
public String bar(String string, double d, int i) {
try {
if (new Random().nextBoolean())
throw new IllegalArgumentException("I don't like your arguments");
}
catch (IllegalArgumentException e) {
return "return value from catch block";
}
return "normal return value";
}
public String zot(double d, int i, String string) {
try {
int n = 2/0;
}
catch (Throwable t) {
return "return value from catch block";
}
return "normal return value";
}
}
ご覧のとおりfoo
、bar
ca. すべてのケースの 50% ですが、zot
常に 0 による除算の例外がスローされます。したがって、出力は実行ごとに異なります。
では、すべての例外が黙って飲み込まれ、ログに記録されない場合、どうすれば何が起こっているのかを知ることができるでしょうか? そのようです:
import java.util.logging.Logger;
public aspect ExceptionLoggingAspect {
final Logger log = Logger.getLogger(ExceptionLoggingAspect.class.getName());
before(Throwable t) : handler(Throwable+) && args(t) {
log.warning(thisJoinPointStaticPart + " -> " + t);
}
}
これは非常にシンプルでエレガントで、アプリケーション全体で機能します。ここにいくつかのテスト出力があります:
Apr 6, 2013 12:15:43 PM ExceptionLoggingAspect ajc$before$ExceptionLoggingAspect$1$3d90b181
WARNING: handler(catch(AuthenticationException)) -> javax.naming.AuthenticationException: wrong password
return value from catch block
Apr 6, 2013 12:15:43 PM ExceptionLoggingAspect ajc$before$ExceptionLoggingAspect$1$3d90b181
WARNING: handler(catch(IllegalArgumentException)) -> java.lang.IllegalArgumentException: I don't like your arguments
return value from catch block
Apr 6, 2013 12:15:43 PM ExceptionLoggingAspect ajc$before$ExceptionLoggingAspect$1$3d90b181
WARNING: handler(catch(Throwable)) -> java.lang.ArithmeticException: / by zero
return value from catch block
this
アドバイスでは、いくつかのプロパティへのアクセスや読み取り/更新など、さらに多くのことができます。