No.get
とset
ポイントカットはメンバーのみに存在し、ローカル変数には存在しません。したがって、この例は、オブジェクトのメンバー変数の割り当てのみに一致しSimpleEntity
ます。これがあなたのやりたいことである場合は、あなたが本当に達成したいことを明確にするために、質問の見出しと内容を言い換えてください. の型宣言の関連部分など、さらにコード コンテキストも提供してくださいSimpleEntity
。
今のところ、特定の型のメンバーが変更されるメソッドの出口点を一致させたいというのが私の最善の推測です。アドバイスの中で正確に何をしたいのか (例えば、メソッド名や割り当てられた値を出力するなど) も教えていただければ、より良いお手伝いができるかもしれません。
更新:pertarget
わかりました。アスペクトのインスタンス化と ITD (型間宣言)を使用して、あなたが望むことを行うソリューションを見つけました。私はパフォーマンスやメモリ消費をテストしていません。それはあなたに任せます。
サンプル エンティティ クラス:
public class SimpleEntity {
private static int currentId = 1;
private int id;
private String name;
private long lastModification;
public SimpleEntity(String name) {
this.id = currentId++;
this.name = name;
}
public void stupidMethod(final int count) {
for (int i = 0; i < count; i++)
name = name.replaceFirst("_[0-9]+$", "") + "_" + i;
}
public int tripleValue(final int value) {
return 3 * value;
}
@Override
public String toString() {
return "SimpleEntity [id=" + id + ", name=" + name + ", lastModification=" + lastModification + "]";
}
}
エンティティを作成および使用するサンプル アプリケーション クラス:
public class Application {
public static void main(String[] args) {
SimpleEntity entity1 = new SimpleEntity("Adam");
entity1.stupidMethod(3);
entity1.tripleValue(11);
entity1.stupidMethod(3);
SimpleEntity entity2 = new SimpleEntity("Eve");
entity2.stupidMethod(3);
entity1.tripleValue(22);
entity2.stupidMethod(3);
}
}
Piotr Blasiak によって要求されたことを行うアスペクト:
public privileged aspect SetterCallingMethodAspect pertarget(entitySetter(SimpleEntity)) {
private static interface MemberChangeDetector {}
private boolean MemberChangeDetector.changed;
declare parents : SimpleEntity implements MemberChangeDetector;
pointcut entitySetter(SimpleEntity entity) :
set (* SimpleEntity+.*) && target(entity) && !within(SetterCallingMethodAspect);
pointcut constructorExecution() :
execution(*.new(..)) && !cflow(adviceexecution());
pointcut methodExecution() :
execution(* *(..)) && !cflow(adviceexecution());
after(SimpleEntity entity) : entitySetter(entity) {
entity.changed = true;
System.out.println(this + ", " + thisJoinPointStaticPart + " -> " + entity);
}
after(SimpleEntity entity) : if(entity.changed) && target(entity)
&& (constructorExecution() || methodExecution())
{
entity.changed = false;
entity.lastModification = System.nanoTime();
System.out.println(
this + ", " + thisJoinPointStaticPart +
" -> update lastModification to " + entity.lastModification
);
}
}
コンソール出力の例:
SetterCallingMethodAspect@bb6ab6, set(int SimpleEntity.id) -> SimpleEntity [id=1, name=null, lastModification=0]
SetterCallingMethodAspect@bb6ab6, set(String SimpleEntity.name) -> SimpleEntity [id=1, name=Adam, lastModification=0]
SetterCallingMethodAspect@bb6ab6, execution(SimpleEntity(String)) -> update lastModification to 1863715110885880
SetterCallingMethodAspect@bb6ab6, set(String SimpleEntity.name) -> SimpleEntity [id=1, name=Adam_0, lastModification=1863715110885880]
SetterCallingMethodAspect@bb6ab6, set(String SimpleEntity.name) -> SimpleEntity [id=1, name=Adam_1, lastModification=1863715110885880]
SetterCallingMethodAspect@bb6ab6, set(String SimpleEntity.name) -> SimpleEntity [id=1, name=Adam_2, lastModification=1863715110885880]
SetterCallingMethodAspect@bb6ab6, execution(void SimpleEntity.stupidMethod(int)) -> update lastModification to 1863715112627443
SetterCallingMethodAspect@bb6ab6, set(String SimpleEntity.name) -> SimpleEntity [id=1, name=Adam_0, lastModification=1863715112627443]
SetterCallingMethodAspect@bb6ab6, set(String SimpleEntity.name) -> SimpleEntity [id=1, name=Adam_1, lastModification=1863715112627443]
SetterCallingMethodAspect@bb6ab6, set(String SimpleEntity.name) -> SimpleEntity [id=1, name=Adam_2, lastModification=1863715112627443]
SetterCallingMethodAspect@bb6ab6, execution(void SimpleEntity.stupidMethod(int)) -> update lastModification to 1863715114328497
SetterCallingMethodAspect@12d03f9, set(int SimpleEntity.id) -> SimpleEntity [id=2, name=null, lastModification=0]
SetterCallingMethodAspect@12d03f9, set(String SimpleEntity.name) -> SimpleEntity [id=2, name=Eve, lastModification=0]
SetterCallingMethodAspect@12d03f9, execution(SimpleEntity(String)) -> update lastModification to 1863715120762834
SetterCallingMethodAspect@12d03f9, set(String SimpleEntity.name) -> SimpleEntity [id=2, name=Eve_0, lastModification=1863715120762834]
SetterCallingMethodAspect@12d03f9, set(String SimpleEntity.name) -> SimpleEntity [id=2, name=Eve_1, lastModification=1863715120762834]
SetterCallingMethodAspect@12d03f9, set(String SimpleEntity.name) -> SimpleEntity [id=2, name=Eve_2, lastModification=1863715120762834]
SetterCallingMethodAspect@12d03f9, execution(void SimpleEntity.stupidMethod(int)) -> update lastModification to 1863715121338606
SetterCallingMethodAspect@12d03f9, set(String SimpleEntity.name) -> SimpleEntity [id=2, name=Eve_0, lastModification=1863715121338606]
SetterCallingMethodAspect@12d03f9, set(String SimpleEntity.name) -> SimpleEntity [id=2, name=Eve_1, lastModification=1863715121338606]
SetterCallingMethodAspect@12d03f9, set(String SimpleEntity.name) -> SimpleEntity [id=2, name=Eve_2, lastModification=1863715121338606]
SetterCallingMethodAspect@12d03f9, execution(void SimpleEntity.stupidMethod(int)) -> update lastModification to 1863715121829729