Aspectノートでは、AspectJについて自分のためにまとめた記述です。 読者の対象は自分、、なのですが、このノートのまとめ方が見やすいと思った方は是非参照して下さい。 一からAspect Oriented Programmingを学習するのには向いていませんので、 他のサイトで学習することをお奨めします。
本ページの内容は、リファレンスとして参照するための情報なので、詳しい意味等について誤りがあります が、これについて、正すつもりはありません。 このページの情報はすべて、正しい情報を知った上で、実際にコーディングする際に時間をかけずに参照することを第一の目的としているからです。
プログラム中に何度も記述しなければならない煩雑な命令を、 プログラム本文から切り離すAOP(Aspect Oriented Programming)を使用するための技術 。 ログ出力のサポートにすごく便利。
AspectJは、サイトからダウンロードした実行可能形式のjarファイルをダブルクリッククリックして実行するだけでよい。 インストールの最後に出てくる画面で要求する、2つの設定について忘れないように行う。 これを忘れないように注意。
aspectJは、ajcコマンドでコンパイルする。 文法は、javacコマンドとほぼ同様である。
aspectJは、ajコマンドで実行する。 実行するクラスファイルは、ajcコマンドでコンパイルしたクラスファイルでなければならない。 (./test/Test.classが存在するものとする。)
aj test.Test
aspectを織り込まないで実行したい場合は、javaコマンドで実行すればよい。
java test.Test
注意としてajコマンドは、 -classpathパラメータを指定すると、元々のCLASSPATH環境変数が反映されなくなる ようだ。この振る舞いは、javaコマンドと異なるので注意。これで1時間悩んだ。。 例えば、次のようなバッチファイルは、エラーを抱え込む可能性が高い。 (mylib.jarやtest.Testはすでにあるものと仮定する)
set MYCLASSPATH=./mylib.jar aj -classpath %MYCLASSPATH% test.Test
上記バッチファイルを実行すると、ClassNotFoundExceptionが発生してしまう。 すでにCLASSPATHに設定されているパスが反映されないためだ。 これを回避するために、 -classpathパラメータを設定しなくてもいいように工夫する。
setlocal set CLASSPATH=%CLASSPATH%;./mylib.jar aj test.Test endlocal
アスペクト(aspect)言語を記述するには、まずは外枠を記述する。 外枠は、Javaのclass宣言をaspectに変えただけである。覚えやすい。
public aspect MyAspect {
}
ジョインポイント(join point)はメソッドのことを指す。 ポイントカット(pointcut)はジョインポイントについて付けた名前である。
class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
void setX(int);
void setY(int);
}
上記クラスがあったとすると、ジョインポイントの作成は、以下のように記述できる。 これは、Pointクラスの戻り値がvoid型、引数がint型のsetXメソッドが呼ばれたことを意味する。
call(void Point.setX(int))
このジョインポイントからatSetX()というポイントカットを作成するには、次のようにする。
pointcut atSetX(): call(void Point.setX(int));
他にも、いろいろな形のジョインポイントを作成することができる。
// setXメソッドの引数を持ったatSetXポイントカットの作成 pointcut atSetX(int x): call(void Point.setX(int)) && args(x); // setXメソッドもsetYメソッドもどちらについても有効なポイントカットの作成 pointcut atSet(): call(void Point.setX(int)) || call(void Point.setY(int)); // ワイルドカードも使える pointcut atSet(): call(void Point.set*(int)); // 呼び出されたPointオブジェクトをポイントカットに持たせることもできる。 pointcut atSet(Point obj, int p): call(void Point.set*(int)) && this(obj) && args(p); // コンストラクタに対するポイントカット pointcut atConstructor(int x, int y): call(Point.new(int,int)) && args(x,y);
アドバイス(Advice)は、ポイントカットが呼び出されたり終了されたりするときに行う動作のことである。 次のように定義する。 ここでloggerはLoggerクラスのオブジェクトとする。
pointcut atSetX(): call(void Point.setX(int));
before(): atSetX() {
logger.debug("X座標が変更されました。");
}
pointcut atSetX(int p): call(void Point.setX(int)) && args(x);
before(int p): atSetX(p) {
logger.debug("X座標が" + p + "に変更されました。");
}
アドバイスには、いくつか種類がある。
before(): // 呼び出し前 after(): // 呼び出し後 after() returning: // 呼び出し正常終了後 after() exception: // 呼び出し例外終了後
キーワード:thisJoinPointは、アドバイスの中で使用することができる。 これは、ジョインポイントの情報を保持している。 その情報を文字列にするには、thisJoinPoint.toString()を用いる。
pointcut atSetX(): call(void Point.setX(int));
before(): atSetX() {
System.out.println("呼び出されたメソッドの情報:" + thisJoinPoint);
}
実行結果は
呼び出されたメソッドの情報:call(void Point.setX(int))
となる。