gpt4 book ai didi

aop - 更改类变量的方法的切入点

转载 作者:行者123 更新时间:2023-12-04 05:27:45 24 4
gpt4 key购买 nike

是否可以编写一个有效的切入点来匹配更改特定类类型的类变量的方法?
这样做的重点是我的类有一个 lastModificationDate,每当类变量发生更改时,我都希望将其更新为最新日期。

方法示例:

public void stupidMethod() {

...
for (int i = 0; i < 100; i++) this.var = whatever;
...
} <--- I want to match here

目前我有这个,但它不是很理想:
after(SimpleEntity entity) : set(* *.*) && target(entity) && !within(SimpleEntityAspect)

最佳答案

getset切入点仅适用于成员,而不适用于局部变量。因此,您的示例将仅匹配 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

关于aop - 更改类变量的方法的切入点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12995824/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com