gpt4 book ai didi

java - spectj - 访问 thisJoinPoint.getTarget() 时出现堆栈溢出错误

转载 作者:行者123 更新时间:2023-12-02 05:55:08 25 4
gpt4 key购买 nike

我试图建议大型第三方应用程序使用以下切入点/建议来拦截所有字段访问:

before(Object target): get(* *) && target(target) && !within(aspect) {
logger.debug("Pointcut: " + thisJoinPoint);
logger.debug("Target: " + target);
}

对于大多数字段访问,这工作正常,但是对于特定访问,第二个调试行会导致 StackOverflowError,并且包含该字段的方法似乎会重复执行到字段访问的行。如果我删除第二个调试行,问题就会消失 - 所以看来使用 thisJoinPoint.getTarget() 会导致问题。 getThis() 也会出现同样的问题,但 thisJoinPoint.getSourceLocation() 或 thisJoinPoint.getSignature() 不会出现此问题

最佳答案

您需要从切入点中排除通知执行或 toString 方法的控制流。

此示例代码复制了您的问题:

驱动程序应用程序:

大多数是自动生成的方法,包括。 toStringhashCode

package de.scrum_master.app;

public class Application {
private String name;

public Application(String name) {
super();
this.name = name;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Application other = (Application) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

@Override
public String toString() {
return "Application [name=" + name + "]";
}

public static void main(String[] args) {
new Application("foo").equals(new Application("bar"));
}
}

建议失败的方面 (StackOverflowError):

package de.scrum_master.aspect;

public aspect FieldAccessLoggingAspect {
before(Object target): get(* *) && target(target) && !within(FieldAccessLoggingAspect) {
System.out.println("Pointcut: " + thisJoinPoint);
System.out.println("Target: " + target);
}
}

具有固定建议的方面:

package de.scrum_master.aspect;

public aspect FieldAccessLoggingAspect {
before(Object target): get(* *) && target(target) && !cflow(adviceexecution()) {
System.out.println("Pointcut: " + thisJoinPoint);
System.out.println("Target: " + target);
}
}

固定建议的替代方案(不太好,但也有效):

package de.scrum_master.aspect;

public aspect FieldAccessLoggingAspect {
before(Object target): get(* *) && target(target) && !cflow(execution(public String Object+.toString())) {
System.out.println("Pointcut: " + thisJoinPoint);
System.out.println("Target: " + target);
}
}

更新:以防万一 cflow() 在您的情况下无法解决问题,因为问题发生在调用堆栈的更深处,您还可以使用 cflowbelow ()。但仅在必要时才这样做。

关于java - spectj - 访问 thisJoinPoint.getTarget() 时出现堆栈溢出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23175689/

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