Type-Safe Pointcut Extension

タイプセーフかどーかは知らないけど、現在の AspectJ での抽象ポイントカットの仕組みは、やや安全ではないと思う。


たとえば、次のような抽象アスペクトがあるとする:


public abstract aspect SetLogging {

protected abstract pointcut targetClass();

before() : call( void set*(..) ) && targetClass() {
// log
}
}

この抽象アスペクトの役割は、指定されたクラスの set*(..) メソッドみのログを取ろうというもの。


たとえば、Point クラスのログを取りたいとすると:


public aspect PointLogging extends SetLogging {

protected pointcut targetClass() : target(Point);
}

とかでよい。


問題は、ポイントカット自体が抽象なのであって、拡張意味自体は、抽象でないということ。つまり、抽象ポイントカットに具体的な定義を与えるときには、誤って次のような定義をしてしまう可能性もある:


public aspect PointLogging extends SetLogging {

protected pointcut targetClass() : within(Point);
}

拡張者側が分かっててやっているんなら問題ないけど、抽象クラスの仕様を取り違えて書いてしまったのであれば、問題だと思う。


解決策の一つは、たとえば:


public abstract aspect SetLogging {

protected abstract pointcut targetClass() : target(abstract);

before() : call( void set*(..) ) && targetClass() {
// log
}
}

とか。


で、拡張者側は、


public aspect PointLogging extends SetLogging {

protected pointcut targetClass() : within(Point);
}

とかするとコンパイル時にエラー。