First step with AspectJ

AOPに進出。勉強書籍はもちろん「AspectJによるアスペクト指向入門」です♪
とりあえずお決まりのHelloWorldから。

まずはターゲット。

public class Hello{
  public static void main(String[] args){
    new Hello().hello();
  }
  public void hello(){
    System.out.println("Hello, AOP world!");
  }
}

次にアスペクト


public aspect Trace1{
  private String Hello.str = "hoge";
  pointcut atHello() : call(void Hello.hello());
  before(Hello h) : atHello() && target(h){
    System.out.println("before Hello:"+h.str + ":" + thisJoinPoint);
  }
  after(Hello h) : atHello() && target(h){
    System.out.println("after Hello:"+h.str + ":" + thisJoinPoint);
  }
}

で、ここまでは普通の教科書どおりです。
これをAJCでコンパイルすると、ミックスされたクラスができるって寸法。
・・・・しかしこれでは面白くないので、ここでひとつつっこんでみた。

Jadを使って逆コンパイル
まずはターゲットのクラス。ふむふむなにやら色々と付け加わっている。。。
なんかFactoryを呼んでる。しっかりbeforeとafterが入ってるな。
でもtry{}finally{}のような形で実践してるかと思いきや、普通に
try{}catch(){}だなあ。。。

makeMethodSigのとこの渡してるありゃあなんだろう?


import java.io.PrintStream;
import org.aspectj.runtime.reflect.Factory;

public class Hello
{

public Hello()
{
Trace1.ajc$interFieldInit$Trace1$Hello$str(this);
}

public static void main(String args[])
{
Hello hello1 = new Hello();
Object aobj[];
org.aspectj.lang.JoinPoint joinpoint = Factory.makeJP(ajc$tjp_0, null, hello1, aobj = new Object[0]);
try
{
Trace1.aspectOf().ajc$before$Trace1$74(hello1, joinpoint);
hello1.hello();
}
catch(Throwable throwable)
{
Trace1.aspectOf().ajc$after$Trace1$ea(hello1, joinpoint);
throw throwable;
}
Trace1.aspectOf().ajc$after$Trace1$ea(hello1, joinpoint);
}

public void hello()
{
System.out.println("Hello, AOP world!");
}

public String ajc$interField$Trace1$str;
public static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_0;

static
{
Factory factory = new Factory("Hello.java", Class.forName("Hello"));
ajc$tjp_0 = factory.makeSJP("method-call", factory.makeMethodSig("1-hello-Hello----void-"), 5);
}
}

次にアスペクトの方はどうなっているかというと・・・・
あ、なんかaspectOf()でちょろっとJad失敗。まあ無理もないか。
基本Aspectインスタンスはシングルトンなのか?どうやらaspectOf()が
createInstance()みたいなもんか・・・・


import java.io.PrintStream;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.NoAspectBoundException;

public class Trace1
{

public Trace1()
{
}

public static void ajc$interFieldInit$Trace1$Hello$str(Hello ajc$this_)
{
ajc$this_.ajc$interField$Trace1$str = "hoge";
}

public static String ajc$interFieldGetDispatch$Trace1$Hello$str(Hello arg0)
{
return arg0.ajc$interField$Trace1$str;
}

public static void ajc$interFieldSetDispatch$Trace1$Hello$str(Hello arg0, String arg1)
{
arg0.ajc$interField$Trace1$str = arg1;
}

public void ajc$before$Trace1$74(Hello h, JoinPoint thisJoinPoint)
{
System.out.println("before Hello:" + ajc$interFieldGetDispatch$Trace1$Hello$str(h) + ":" + thisJoinPoint);
}

public void ajc$after$Trace1$ea(Hello h, JoinPoint thisJoinPoint)
{
System.out.println("after Hello:" + ajc$interFieldGetDispatch$Trace1$Hello$str(h) + ":" + thisJoinPoint);
}

public static Trace1 aspectOf()
{
ajc$perSingletonInstance;
if(ajc$perSingletonInstance == null) goto _L2; else goto _L1
_L1:
return;
_L2:
throw new NoAspectBoundException();
}

public static boolean hasAspect()
{
return ajc$perSingletonInstance != null;
}

private static void ajc$postClinit()
{
ajc$perSingletonInstance = new Trace1();
}

public static final Trace1 ajc$perSingletonInstance;

static
{
ajc$postClinit();
}
}