gpt4 book ai didi

java - 为什么匿名类方法调用方法时aop无法执行?

转载 作者:太空宇宙 更新时间:2023-11-04 07:20:18 29 4
gpt4 key购买 nike

这是我的自定义注释AnnoLogExecTime和类AOP:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AnnoLogExecTime {

}

@Aspect
@Service
public class AOP {
Logger logger = LoggerFactory.getLogger(AOP.class);

@Around("execution(@com.judking.general.aop.AnnoLogExecTime * *(..))")
public Object calExecTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
Method method = signature.getMethod();

long t1 = System.currentTimeMillis();
Object obj = proceedingJoinPoint.proceed();
long t2 = System.currentTimeMillis();

logger.info("method `"+method.getName()+"` takes "+(t2-t1)+"ms");
return obj;
}
}

测试用例如下:

@Service
class A {
public void go() {
B b = new B() { //Anonymous class B
@Override
public void exec() {
aopMethod();
}
};
b.exec();
}

@AnnoLogExecTime
public void aopMethod() {
System.out.println("aopMethod");
}
}

@Service
class B {
public void exec() {
System.out.println("exec");
}
}

当我调用a.aopMethod()时,AOP.calExecTime被连接到a.aopMethod()

但是,如果我调用 a.go(),它使用匿名类 B 实例来调用 a.aopMethod(),那么 AOP.calExecTime连接到 a.aopMethod()

谁能给我解释一下这个现象吗?请给我一种在匿名类的情况下解决这个问题的方法。非常感谢!

最佳答案

这并不完全是因为它是一个匿名内部类。 您遇到的是 AOP 代理的限制。

当你有

A a = ...; // get proxy

代理本身将实际实例包装在包装器实例中。当您通过调用与此包装器实例交互时

a.aopMethod();

代理拦截器拦截调用并可以执行通知。

这适用于您调用的电话

a.go()

是否有连接点。相反,没有任何东西拦截该调用,并且对 go() 的调用会通过拦截器,并在实际实例上调用该方法

actualA.go();

当您创建匿名内部类并具有

@Override
public void exec() {
aopMethod();
}

它隐式地做

@Override
public void exec() {
A.this.aopMethod();
}

它绕过代理,因为您是在实际实例上调用它,而不是包装器。

您可能没有使用 Spring 来生成代理,但是their documentation explains this pretty well.

关于java - 为什么匿名类方法调用方法时aop无法执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19439801/

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