Explicit JoinPoints or JoinPoint Class

AspectJ における一つの制限(ただし、欠点とは限らない)は、あらかじめ決められたジョインポイントのみが存在すること。したがって、プログラマが望むすべてのジョインポイントとなりうるポイントが、ジョインポイントとは限らない。たとえば、ローカル変数に関するジョインポイントや、for や if に関するジョインポイントは存在しない。


一つの解決策は、ダミーのジョインポイントとなりうるものを明示的にコードに挿入すること:


public class Main {
public static void main(String[] args) {

System.out.println("aaa");

setArg("xxx");

System.out.println("bbb");
}

private static void setArg(String arg) { }
}


public aspect MyAspect {
before(String arg) : args(arg) && call( void Main.setArg(String) ) {
System.out.println("arg = " + arg);
}
}
しかし、多少の不自然さを感じる。いっそのこと、明示的に定義したジョインポイントだということを直接表現したほうがいいのでは? たとえば

public class ArgJoinPoint {
public ArgJoinPoint(String arg) { }
}

public class Main {

public static void main(String[] args) {

System.out.println("aaa");

new ArgJoinPoint("xxx");

System.out.println("bbb");
}
}


public aspect MyAspect {
before(String arg) : args(arg) && call( ArgJoinPoint.new(String) ) {
System.out.println("arg = " + arg);
}
}

さらには、もし、ジョインポイントを名前だけで判断できるようなのであるとすると、わざわざジョインポイントごとにクラスを書くのではなく:


public class JoinPoint {
public JoinPoint(String jpName, String arg) { }
}

public class Main {

public static void main(String[] args) {

System.out.println("aaa");

new JoinPoint("setArg", "xxx");

System.out.println("bbb");
}
}


public aspect MyAspect {
before(String name, String arg) :
args(name, arg) && call( JoinPoint.new(String, String) )
{
if (name.equals("setArg")) {
System.out.println("arg = " + arg);
}
}
}
というふうにできるかもしれない。


さらには、より使いやすくするために:


public class JoinPoint {

public pointcut jp(String name, String arg) :
args(name, arg) && call( JoinPoint.new(String, String) );

public JoinPoint(String name, String arg) { }
}


public aspect MyAspect {
before(String name, String arg) :
JoinPoint.jp(name, arg) && if ( name.equals("setArg") )
{
System.out.println("arg = " + arg);
}
}
と書けるかもしれない。