かずきのBlog

C#やJavaやRubyとメモ書き

目次

Blog 利用状況

ニュース

わんくまBlogが不安定になったため、前に書いてたはてなダイアリーにメインを移動します。
かずきのBlog@Hatena
技術的なネタは、こちらにも、はてなへのリンクという形で掲載しますが、雑多ネタははてなダイアリーだけに掲載することが多いと思います。
コメント
プログラマ的自己紹介
お気に入りのツール/IDE
プロフィール
経歴
広告
アクセサリ

書庫

日記カテゴリ

AspectJ5のAnnotationを使った記法 その1

AspectJに割りと最近のバージョンからかけるようになったAnnotationを使った記法がある。
これが、意外と情報が少なめってことで自分用のメモ

アスペクトの定義

まずは基本のアスペクトの定義から。これは、普通のクラスにAspectアノテーションをつけるだけでOK。

package kazuki;

import org.aspectj.lang.annotation.Aspect;

@Aspect
public class SimpleAspect {

}

ポイントカットの定義

ポイントカットの定義は、戻り値がvoidのpublicなメソッドにPointcutアノテーションをつけることで出来る。
Pointcutアノテーションの括弧の中に昔からある"execution(* *.*(..))"みたいな定義を書けばOK

package kazuki;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SimpleAspect?{
    @Pointcut("execution(* *.*(..))")
????public void somePointcut() {

????}
}

アドバイスの定義

あとは適切なアドバイスさえ書けばアスペクト指向できちゃう。
アドバイスの定義もアノテーション付きのメソッドでOK。
代表的なのに下のようなのがある

  • Before:前
  • After:後
  • Around:周囲?
  • AfterReturning:return後
  • AfterThrowing:throw後

例えば、全てのメソッドが呼ばれる前にsample adviceと呼ばれるようにするには下のように書けばOK

package kazuki;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SimpleAspect {
    @Pointcut("execution(* *.*(..))")
????public void somePointcut() {

????}

????@Before("somePointcut()")
????public?void someAdvice() {
????????// ここに処理を書く
????????System.out.println("sample advice");
????}
}

JoinPoint/ProceedingJoinPoint

Aroundを使うと、あるメソッドの処理とかをまるごと横取りすることができる。
その際に、もとの処理を呼び出すためにProceedingJoinPointってのを使う。 因みに、別にもとの処理を呼び出す必要がないときは普通のJoinPointを使う。 これらのクラスを使うと、メソッドの引数や名前やアスペクトを適用したクラスのインスタンスなんかが取れたりする。
早速使ってみた。

package kazuki;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SimpleAspect?{
    @Pointcut("execution(* *.*(..))")
????public?void somePointcut() {

????}

????@Before("somePointcut()")
????public void someAdvice(JoinPoint thisJoinPoint) {
??????System.out.println(thisJoinPoint.getThis()); // Object
??????System.out.println(thisJoinPoint.getArgs()); // Object[]
????}
}

今まで動作させてなかったけど、このアスペクトを組み込んでハローワールドを動かすとどういう結果になるかをやってみた

package kazuki;

public class Main {
??public static void main(String[] args) {
????System.out.println("Hello world");
??}
}

実行すると下のような結果になる。getThisはstaticメソッドなのでnullになってる。

null
[Ljava.lang.Object;@e89b94
Hello world

Hello worldをちょっと大げさにインスタンスメソッドを使うように改造してみた。

package kazuki;

public class Main?{
??public static void main(String[] args) {
????new Main().sayHello();
??}

??private void sayHello() {
????System.out.println("Hello world");
??}
}

これを実行すると下のようになる。sayHelloメソッドの呼び出しの時にはgetThisはnullじゃなくてちゃんとしたインスタンスが返ってきている。

null
[Ljava.lang.Object;@e89b94
kazuki.Main@13e205f  <== コイツがsayHello呼び出しの時のgetThis
[Ljava.lang.Object;@1bf73fa
Hello world

ほかにも何個かメソッドがあるけど、必要に応じて使っていけばいいと思う。

さて、もう1つのJoinPointのProceedingJoinPointを試してみようと思う。
これは、Aroundアドバイスで良く使う。 Aroundは、対象となる処理をまるまる横取りするような動きをする。なので、もとの処理を呼び出さないと完全にもとの処理が実行されない!
ためしにログを吐くようなアスペクトを作ってみた。

package kazuki;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SimpleAspect {
  @Pointcut("execution(* *.*(..))")
??public void somePointcut() {

??}

??@Around("somePointcut()")
??public Object log(ProceedingJoinPoint thisJoinPoint) throws Throwable {
????try {
??????System.out.println("BEGIN: " + thisJoinPoint.getSignature().getName());
??????return thisJoinPoint.proceed(); // ここで本来の処理を呼び出してる
????} finally {
??????System.out.println("END: " + thisJoinPoint.getSignature().getName());
????}
??}
}

このアスペクトを適用して、さっきのHello worldを実行すると下のような結果になる。メソッドの呼び出しが漏れなくトレースできてる。

BEGIN: main
BEGIN: sayHello
Hello world
END: sayHello
END: main

とりあえず今日はここまで。
本当に基本的だけど、基本だからこそよく使うあたりだと思う。ポイントカットの定義[コード内でのexecution(* *.*(..))の部分)]の書き方はAspectJのドキュメントに載ってる!はず!!(英語だけど)
そこをマスターすれば、ここにあることだけで結構できるんじゃないかな。

投稿日時 : 2007年8月25日 22:47

Feedback

# re: AspectJ5のAnnotationを使った記法 その1 2007/08/27 0:06 凪瀬

なるほどなるほど。
なかなか触る機会がないのですが、試してみたいところですね。

# re: AspectJ5のAnnotationを使った記法 その1 2007/08/27 17:38 かずき

EclipseのEuropaの更新サイトからさくっと入れるだけで使えるようになるんでお手軽ですよ。

本番で使うのは、結構難しいかもしれないですけど…

# new era casquette 2013/03/23 21:30 http://e55.fr/

Not any woman or man will be worth any tears, and so the individual who is triumphed in‘h get you to watchword. new era casquette http://e55.fr/

# casquette fox 2013/03/23 21:31 http://e66.fr/

An absense of male or female might be worth a crying, plus the an individual that is undoubtedly won‘l make you holler. casquette fox http://e66.fr/

# destockchine 2013/03/24 0:49 http://d77.fr/

Want your bookkeeping with the benefit, quantity buddies. destockchine http://d77.fr/

# destockchine 2013/03/24 0:49 http://c99.fr/

Anywhere int he planet you are someone, on the other hand to just one particular person you are everybody. destockchine http://c99.fr/

# destockmania 2013/04/03 7:13 http://www.ruenike.com/chaussure-femme-c-4.html/

Do not ever glower, virtually all one is pitiful, since we can never predict that's falling over excited about your own grinning. destockmania http://www.ruenike.com/chaussure-femme-c-4.html/

# laredoute 2013/04/07 7:22 http://ruezee.com/

A suitable bro most likely is not a pal, although a pal will be an actual bro. laredoute http://ruezee.com/

# asos 2013/04/08 15:25 http://rueree.com/

Irrrm a sucker for happened a result of your identity, yet somehow a result of who exactly My business is their feel along. asos http://rueree.com/

タイトル
名前
Url
コメント