はじめに

最近、 アスペクト指向プログラミング(AOP)が注目を浴びています。AOPについての多くはここでは多く語りませんが、JavaでAOPを実現する最もメジャーな実装としてAspectJがあります。 このAspectJはJavaとは異なる独自の文法を利用しており、Javaプログラマが導入するには敷居が高いという最大の問題がありました。これに対して、近年、SpringAOPやJBossAOPと行ったJavaクラスベースのAOPを実現するツールが現れてきました。これらのツールでは独自文法を覚える必要がなく、アスペクトをJavaのコードで記述することができます。PointCut?やAdviceはXMLで記述する必要がありますが、これらのツールでは、AspectJに比べると非常に簡単にAOPを実現できます。このJavaクラスベースのAOPツールの中でも今最も注目を集めているのがBEAの支援を受け、CodeHausで開発されているAspectWerkzです。

AspectWerkzの特徴

  • POJOでアスペクトを定義し、XMLでPointCut?、Adviceを定義します。非常に簡単にAOPを導入することができます。
  • 非常に高速に動作します。一般的にJavaクラスベースのAOPではリフレクションやバイトコード操作を行いますが、最適なコード変換/生成を行わないと高いパフォーマンスを得ることはできません。AspectWerkzはJavaクラスベースでありながら高いパフォーマンスを実現しています。詳細はベンチマーク(http://docs.codehaus.org/display/AW/AOP+Benchmark )をご覧下さい。
  • XDoclet2、PiccoContainer等、数々の先進的なオープンソースを生み出しているCodeHausで開発されています。
  • スポンサーにBEAがついています。AspectWerkzの開発者はBEAから給与を貰いながらAspectWerkzを開発しています。
  • On The FlyによるWeavingとStaticなWeavingの両方をサポートしています。
  • Eclipseのプラグインが提供されていますhttp://docs.codehaus.org/display/AW/Eclipse+plugin
  • AspectWerkzの機能はAspectJ5へ統合されることになりました。

HelloWorld?

では、HelloWorld?を動かしてみましょう。

test/HelloWorld?.java

アスペクトを織り込まれるソースです。

package test;

public class HelloWorld {

   public static void main(String args[]) {
       HelloWorld world = new HelloWorld();
       world.greet();
   }

   public void greet() {
	return "hello";
   }
}

aspect/MyAspect?.java

アスペクトです。

package aspect;

import org.codehaus.aspectwerkz.joinpoint.JoinPoint;

public class MyAspect {

   public void beforeGreeting(JoinPoint joinPoint) {
       System.out.println("before greeting...");
   }

   public void afterGreeting(JoinPoint joinPoint) {
       System.out.println("after greeting...");
   }
}

META-INF/aop.xml

PointCut?をaop.xmlで指定します。クラスパス上のMETA-INF/aop.xmlに置くと、aspectwerkzにより自動的に読み込まれます。ここでは、test.HelloWorld?クラスのgreetメソッドをポイントカットとして定義し、MyAspect?クラスのbeforeGreegingメソッドをtype=before(実行前にアスペクトを実行)、afterGreetingメソッドをtype=after(実行後にアスペクトを実行)するように設定しています。

<?xml version='1.0' ?>
<aspectwerkz>
   <system id="AspectWerkzExample">
       <package name="aspect">
           <aspect class="MyAspect">
               <pointcut name="greetMethod"
                         expression="execution(* test.HelloWorld.greet(..))"/>
               <advice name="beforeGreeting"
                       type="before" bind-to="greetMethod"/>
               <advice name="afterGreeting"
                       type="after" bind-to="greetMethod"/>
           </aspect>
       </package>
   </system>
</aspectwerkz>

コンパイル、実行

上記のファイルを次のように配置します。

hello/
 test/
    HelloWorld.java
 aspect/
    MyAspect.java
 aop.xml

helloディレクトリで次のようにしてコンパイル。実行。

> javac test/HelloWorld.java
> javac -classpath ".../aspectwerkz-2.0Rc2.jar;." aspect/MyAspect.java
> set JAVA_HOME=...
> set ASPECTWERKZ_HOME=..
# コンパイラでアスペクトをWeavingします。
> %ASPECTWERKZ_HOME%\bin\aspectwerkz.bat -offline META-INF/aop.xml -cp . .
> java -classpath
  "%ASPECTWERKZ_HOME%\lib\aspectwerkz-2.0.RC2.jar;%ASPECTWERKZ_HOME%\lib\aspectwerkz-core-2.0.RC2.jar;." 
       test.HelloWorld
before greeting...
HelloWorld!
after greeting...

実行結果をみると、greetメソッドの前後にアスペクトがWeavingされているのが確認できます。

Class load time weaving

上記の例は静的にコンパイルしてアスペクトをWeavingしますが、AspectWerkzはクラスをロードしたときにWeavingする機能があります。この機能を利用すると、静的にコンパイルする必要がなくなります。クラスロード時にWeavingするには、次のようにaspectwerkzコマンドからJavaクラスを実行します。

%ASPECTWERKZ_HOME%\bin\aspectwerkz.bat -cp . test.HelloWorld

メモ

  • after throwing advice
    <advice name="afterThrowing"
            type="after throwing(java.lang.Exception)"
            bind-to="test"/>
    スローされた例外に応じてAspectを実行する。
  • after returning advice
    <advice name="afterReturing" 
            type="after returning(java.lang.String)"
            bind-to="test"/>
    返却されたクラスに応じてAspectを実行する。
  • around advice
     <advice name="aroundAdvice" 
            type="around"
            bind-to="test"/>
public class MyAspect {
..
   public Object aroundAdvice(JoinPoint joinPoint) throws Throwable{
	  Object msg = joinPoint.proceed();
	  return "hello " + msg;
   }
public class Hello {
  public String test(){
    return "test";
  }
}

aroundAdviceで指定されたメソッドがtestメソッドのreturn文実行後に実行される。上記の例では、"test"を返却するときに、aroundAdviceが呼ばれ、"hello "文が先頭に追加され、"hello test"となる。

  • 引き数の取得
    public void before(JoinPoint jp) {
      MethodRtti a = (MethodRtti)jp.getRtti();
      Object o[] = a.getParameterValues();
      System.out.print("(");
      for(int i=0;i<o.length-1;i++){
        System.out.print(o[i]+",");
      }
      System.out.println(o[o.length-1]+")");
    }

Eclipse

Eclipseプラグイン(http://docs.codehaus.org/display/AW/Eclipse+plugin )を利用すると、Eclipseの自動コンパイル機能で、自動的にアスペクトがWeavingされる。アスペクトはメタデータとMETA-INF/aop.xmlで定義する。 海岸の人魚を引用します の 最も大衆向きの実用性の健康な飲食の指針を備えます(4) 最も大衆向きの実用性の健康な飲食の指針を備えます(4)    しょっぱい味の食品:腎臓になります。しょっぱい味の食品が腎臓を補うことがいます、下達し引火します、乾燥していることを潤して風を取り除きます、熱を下げるのがしみますぬれます、明目の効果。しょっぱい味は生命の活動所を維持したので、しかしきっと食べる量を制御して、少量の食用、きわめて有利です。しょっぱい味の食品は塩、しょう油、顔の味噌の以外、多く海産物で、例えばコンブ、ノリ、海藻、クラゲ、イカなど。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-10-19 (火) 21:21:36 (2891d)