山下寛人オフィシャルブログ

オイシックス株式会社 執行役員 システム本部長 山下寛人の公式ブログです。

AspectJの使い方

Aspectなんて知らない人、多いですよね。一時AOPと言われ注目されたJavaの技術です。今ではAOPのまま利用することはほとんどないと思います。しかしアノテーションでいろんな処理を追加するところのベースはAOPになっていることが多いと思われます。アノテーションは利用している人が多いと思うので間接的に利用はかなりされていると思います。

以前JBossAOPをやってすごく少ない工数で問題を解決したことがありました。今回JBossから移行するにあたりJettyでAspectJを使って見ることにしました。しかし生AOPは結構大変でした。使っている人があまりいないせいかgoogleに情報が少なく公式ドキュメントくらいしかありません。公式ドキュメントもhow to形式で書いてくれていないし結構いろいろなやり方があるらしく量も多いので大変です。そこでうまくできたやり方をhow to形式で紹介します。

独自言語で事前コンパイルなどするやり方もあるようですが手軽に使えるload time weavingというやり方をします。事前コンパイル不要です。またアノテーションを使ってaspectを記述します。

JavaSE 6
AspectJ 1.8.6

AspectJを公式サイトからダウンロード
未確認ですがMavenやGradleを使ったほうが早いでしょう。
とはいえ依存jarもないのでjarだけでも簡単です。

・jarを展開。私はunzipコマンドで展開しました。

・中にあるlib/aspectjweaver.jarをクラスパスに追加。

aspectクラスを作成。

・クラスの前に@Aspectを宣言
@Aspect
public class Capture {

・織り込みたい処理をメソッドとして記述
@AfterReturning(pointcut="call(String com.oisix.yamashita.AspectSample.sayHello())", returning="hello")
public void afterSayHello(Object hello) {
    System.out.println("captured:" + hello);
}

「AfterReturning」はメソッドの実行が正常に終わった後に実行するという意味です。「pointcut=」のところはどのメソッド実行か定義しています。callの中にメソッド名を入れます。ワイルドカードコンストラクタの指定方法などもありますがそこらへんは公式サイトのドキュメントを見ましょう。「returning="hello"」の部分は返り値を取れるようにしています。続くメソッドの引数に「Object hello」とあります。ここの名前を合わせることで返り値が入ってきます。あとはメソッドの中で好きなように料理します。

・クラスパスの通っているところにMETA-INF/aop.xmlファイルを作成。

aspectクラスをファイル内に記述。
<aspectj>    
  <aspects>        
    <aspect name="com.oisix.yamashita.aspect.Capture"/>    
  </aspects>
</aspectj>

・実行時に-javaagent:パス/aspectjweaver.jarをjavaコマンドにつけて実行
eclipseならrun configuration,arguments,VM argumentsの中。
Jettyだったらstart.iniの中に追加します。

以上でできるはずです。