今回紹介するAspectWerkzは、Codehausで開発されているアスペクト指向フレームワークである。CodehausはJavaのオープンソースソフトウェアの開発を行っているプロジェクトであり、軽量コンテナである「PicoContainer」を開発していることでも知られている。このAspectWerkzは米BEAシステムズがスポンサーとなって開発を支援しているが、ライセンスはLGPL形式で配布されているため、AspectJやJBossAOPと同様に無償での商用利用が可能である。
AspectWerkzの特徴はPOJOであること、XMLの定義ファイルを用いてポイントカットやアドバイスを定義すること、そしてアノテーション(JSR-175)をサポートしていることなどが挙げられ、JBoss AOPとの共通点も多い。またEclipseプラグインが提供されていることなども開発者にとっては喜ばしいことだろう。さらに、公開されているベンチマークテストによって示されるように、非常にパフォーマンスが高いことも長所として挙げることができる。
ところで、AspectWerkzに関しては、この記事を執筆中に興味深いコメントが発表された。連載の第2回目「AspectJから学ぶアスペクト指向の理解」で紹介した、eclipse.orgによって開発されているAspectJと統合され、AspectJ5という名前で開発が続けられるようだ。現在、ちまたではさまざまなアスペクト指向フレームワークが乱立しており、開発者が混乱するもととなっている。しかしながら、今後は主流となるAOPフレームワークに統一されていくのではないだろうか。
では早速AspectWerkzをインストールして、いつものように簡単なサンプルプログラム「Hello, AspectWerkz」を実行してみよう。まずはAspectWerkzのサイトからアーカイブをダウンロードする。
原稿執筆時点での最新バージョンはAspectWerkz 2であり、RC3版(aspectwerkz-2.0.RC3)がリリースされている。まずはこのファイルをダウンロードし、任意のディレクトリに解凍・展開する。
次に環境変数の設定を行う。AspectWerkzを使用するためには環境変数「ASPECTWERKZ_HOME」を設定しなければならない。この環境変数にはAspectWerkzのホームディレクトリを指定する。
さらに、AspectWerkzの「bin」ディレクトリを環境変数PATHに追加し、「lib」ディレクトリ下にある2つのJARファイル「aspectwerkz-2.0.RC3.jar」と「aspectwerkz-core-2.0.RC3.jar」をクラスパスに設定しておく。
ここまでで準備は完了である。では実際にAspectWerkzを使ったアスペクトのウィービングを行ってみよう。
まずは、前回、前々回に使用した「Messenger」クラスと「Tester」クラスを用意する。すでに連載記事中で説明しているようにシンプルなJavaのプログラムである。
public class Messenger { public static void printMessage(String name) { System.out.println(name); } }
public class Tester { public static void main(String[] args) { Messenger.printMessage("AspectWerkz"); } }
次にアスペクトを定義する。AspectWerkzではJBossAOPと同様、POJOによってアスペクトを定義するため、以下のような通常のJavaクラスを作成すればよい。
import org.codehaus.aspectwerkz.joinpoint.JoinPoint; public class GreetingAspect { public void beforeGreeting(JoinPoint joinPoint) { System.out.print ("Hello, "); } }
いつもと同じように「Hello,」を表示するアドバイスの実装を行っている。ここでアドバイスとして呼び出されるメソッドはJoinPointオブジェクトを引数に受け取るようにしておけば、後々ジョインポイントの情報を取得することができる。
ポイントカットやアドバイスはXMLファイルを用いて次のように定義する。このファイルは「META-INF」ディレクトリ下に「aop.xml」という名前で格納しておくことで、アプリケーション実行時に自動的に読み込まれる。
<aspectwerkz> <system id="AspectWerkzExample"> <aspect class="GreetingAspect"> <pointcut name="greetMethod" expression="execution(* Messenger.printMessage(..))" /> <advice name="beforeGreeting" type="before" bind-to="greetMethod" /> </aspect> </system> </aspectwerkz>
このaop.xmlでの記述を簡単に説明しておこう。
3つのファイルが用意できたら、ソースをコンパイルしてアスペクトをウィービングし、プログラムを実行してみよう。AspectWerkzでは、まず通常のjavacでコンパイルを行い、その後アスペクトのウィービングを行う。
> javac *.java
この時点ではアスペクトのウィービングは行われていない。試しにTesterを実行してみよう。
> java Tester AspectWerkz
printMessage()メソッドの実行結果が表示される。次にアスペクトのウィービングを行ってみよう。次のようにaspectwerkzコマンドを用い、-offlineオプションにaop.xmlファイルの場所を指定し、最後に対象となるファイルの配置されているディレクトリを指定する。
> aspectwerkz -offline META-INF/aop.xml . ( 4 s )SUCCESS: .
ウィービングが完了したら、もう1度アプリケーションを実行する。
> java Tester Hello, AspectWerkz
アドバイスで実装した「Hello, 」を表示する処理が差し込まれていることが分かる。この例ではコンパイル時の静的なウィービングを紹介したが、AspectWerkzでは実行時の動的なウィービングもサポートしている。その場合にはアプリケーション実行時にjavaコマンドではなくaspectwerkzコマンドを用いる。
いったん、アスペクトのウィービング済みクラスファイルを削除し、もう一度コンパイルから動的なウィービングによる実行を試してみよう。
> javac *.java >aspectwerkz -cp . Tester AspectWerkz - INFO - Pre-processor org.codehaus.aspectwerkz.transform. AspectWerkzPreProcessor loaded and initialized Hello, AspectWerkz
AspectWerkzで実行時のジョインポイントの情報を取得するにはorg.codehaus.aspectwerkz.joinpointパッケージに定義されているRtti(ReturnTime Type Information)インターフェイスを用いる。Rttiオブジェクトから得られる情報はロギングやトレースの際に必要となるだろう。
Rttiを取得するには次のようにJoinPointオブジェクトのgetRtti()メソッドを使用する。
Rtti rtti = JoinPoint.getRtti();
Rttiオブジェクトが取得できれば、例えば次のようにgetDeclaringType()メソッドやgetName()メソッドを呼び出すことでジョインポイントのクラス名やメソッド名を表示することができる。
System.out.println("Class:" + rtti.getDeclaringType()); System.out.println("Name:" + rtti.getName());
今回はAspectWerkzを紹介したが、冒頭でも伝えたように今後はAspectJ5と統合されていく流れになっている。この1年ほどでAOPフレームワークも洗練されてきており、ある程度統一も図られていくだろう。これまではアスペクト指向とAOPの基礎的な概念およびAOPフレームワークの導入について簡単に紹介してきたが、次回はもう少し実践的なAOPの活用例を紹介したい。
Copyright © ITmedia, Inc. All Rights Reserved.