Java 为什么可以';当从匿名类调用方法时,aop将执行';方法?
这是我的自定义注释Java 为什么可以';当从匿名类调用方法时,aop将执行';方法?,java,aspectj,anonymous-inner-class,Java,Aspectj,Anonymous Inner Class,这是我的自定义注释AnnoLogExecTime和类AOP: @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AnnoLogExecTime { } @Aspect @Service public class AOP { Logger logger = LoggerFactory.getLogger(AOP.class); @Aroun
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.calexetime
连接到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生成代理,但这并不完全是因为它是一个匿名内部类您遇到的是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来生成代理,但是