今まで AspectJ の導入の仕方や Eclipse へのプラグインのやはり導入の仕方などを見てきましたが、今回はごくごく簡単な例でアスペクト指向がどんなものかを見ていきたいと思います。
Eclipse はやはりちょっと独特ですし、基本としてシンプルに AspectJ が導入されただけの環境で見ていきましょう。
まず最初に、 HelloWorld みたいなもので単純にメッセージを送信するようなクラスを例にして説明してみたいと思います。
メッセージだけを引数とする send と、呼びかけ先 (宛先) とメッセージを引数にとる send メソッドのあるクラスとします。
public class Message {
public static void send(String message) {
System.out.println(message) ;
}
public static void send(String to, String message) {
System.out.println(to + ": " + message) ;
}
}
|
クラスをテストするためのテストクラスを作成しています。
テストクラスなのでメソッドはシグネチャを両方ともテストしてみています。
public class SendTest {
public static void main(String[] args) {
Message.send("メッセージは読めますか?");
Message.send("田中さん", "メッセージです");
}
}
|
コンパイルと実行結果はこんなかんじですね。

例えばこのクラスで、他にもいろいろな引数をとるメソッドがたくさんある、という想定をしてみましょう。
または、このクラスを拡張した派生クラスがたくさんある、という想定でもかまいません。
そういったクラス/メソッド群に対して統一した処理を追加したい、という要件が後から出てくることがままあります。
たとえば、ログをメソッドの前後で取りたい、セキュリティを強制したい、などといった要件が典型ですね。
ここでアスペクト指向の登場です。
アスペクト指向の特徴はいろいろなクラスに横断した作業を簡単に "aspect" として実現できる、というところにあります。
話を簡単にするため、今回はどんな引数をとる send メソッドに対しても必ず実行前に「こんにちは!!」と入れる、というようにしたい、としましょう。
AspectJ でかくとこんなかんじになります。いわゆる「クラス」ですがアスペクト指向のことばでは「アスペクト」といいます。
参照しながら次を読んでいってください。
public aspect SayHelloAspect {
pointcut SendMessage() : call(* Message.send(..));
before() : SendMessage() {
System.out.println("こんにちは!! ");
}
}
|
Message クラスの send メソッドですべての引数をとる、という定義が
call(* Message.send(..))
というようになります。(これを "JoinPoint" といいます)
これを後で識別するために名前をつけるのが、その前についている
pointcut SendMessage() :
になります。(これを "PointCut" といいます)
この定義したクラス/メソッドの集合・組み合わせに対してタイミングの指定が
before() :
で、(before/after/around の指定が可能です)
そのタイミングで実行したい処理(これを "Advice" といいます)が
{ System.out.println("こんにちは!! "); }
になります。
見たとおり、処理は Java でかくことができます。
以上の 3 つのソースを ajc という AspectJ のツールでコンパイルします。
コンパイル実行後は通常の Java のクラスになりますので、java コマンドで実行可能です。
実行結果もあわせて見てみましょう。
Message クラスや SendTest クラスには何も変更せずに実行結果が変わったことが確認できますね。

別のマシンに持っていっても、aspectrt.jar を追加でクラスパスに入れておけば実行可能です。

さらに Java なのでもちろん別アーキテクチャのマシンでも OK です。

|
|