为什么这个 AspectJ 方法签名表达式匹配子类型中被覆盖的方法?
Why does this AspectJ method signature expression match overwritten methods in subtypes?
我定义了两个类
public class A{
public A myMethod(){
return this;
}
}
public class B extends A{
@Override public B myMethod(){
return this;
}
}
和切入点 execution(public A+ A.*(..))
.
我很惊讶这两种方法都被切入点选中了。为什么我没有在 myMethod()
的定义类型的类型名称后添加加号?
如果+
已经存在匹配子类型,为什么AspectJ的设计不一致?
方法执行被捕获,因为您正在拦截基 class 中定义的方法。当在 subclass 中被覆盖时,它仍然会被匹配。切入点 不会 匹配 subclass 中定义的任何方法。
让我重命名您的 classes 以使代码更具可读性,并将其变成 MCVE:
基础class:
package de.scrum_master.app;
public class Base {
public Base baseAction() {
return this;
}
}
Subclass 重写方法:
package de.scrum_master.app;
public class Sub extends Base {
@Override
public Sub baseAction() {
return this;
}
public Sub subAction() {
return this;
}
}
请注意,我在 subclass 中添加了另一种方法,它不包含在基础 class.
中
驱动申请:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new Base().baseAction();
System.out.println("-----------------");
new Sub().baseAction();
System.out.println("-----------------");
new Sub().subAction();
}
}
看点:
package de.scrum_master.app;
import de.scrum_master.app.Base;
public aspect MyAspect {
before() : execution(Base Base.*(..)) {
System.out.println("Base Base.*(..) -> " + thisJoinPoint);
}
before() : execution(Base+ Base.*(..)) {
System.out.println("Base+ Base.*(..) -> " + thisJoinPoint);
}
before() : execution(Base Base+.*(..)) {
System.out.println("Base Base+.*(..) -> " + thisJoinPoint);
}
before() : execution(Base+ Base+.*(..)) {
System.out.println("Base+ Base+.*(..) -> " + thisJoinPoint);
}
}
控制台日志:
Base Base.*(..) -> execution(Base de.scrum_master.app.Base.baseAction())
Base+ Base.*(..) -> execution(Base de.scrum_master.app.Base.baseAction())
Base Base+.*(..) -> execution(Base de.scrum_master.app.Base.baseAction())
Base+ Base+.*(..) -> execution(Base de.scrum_master.app.Base.baseAction())
-----------------
Base Base.*(..) -> execution(Sub de.scrum_master.app.Sub.baseAction())
Base+ Base.*(..) -> execution(Sub de.scrum_master.app.Sub.baseAction())
Base Base+.*(..) -> execution(Sub de.scrum_master.app.Sub.baseAction())
Base+ Base+.*(..) -> execution(Sub de.scrum_master.app.Sub.baseAction())
-----------------
Base+ Base+.*(..) -> execution(Sub de.scrum_master.app.Sub.subAction())
如果您还在方法签名中的 class 名称中添加 +
,您能看出如何仅捕获 Sub Sub.subAction()
吗?这也是 +
的作用以及您需要它的原因的一个很好的例子。 return 类型和方法签名都需要 Base+
才能捕获 Sub Sub.subAction()
!
我定义了两个类
public class A{
public A myMethod(){
return this;
}
}
public class B extends A{
@Override public B myMethod(){
return this;
}
}
和切入点 execution(public A+ A.*(..))
.
我很惊讶这两种方法都被切入点选中了。为什么我没有在 myMethod()
的定义类型的类型名称后添加加号?
如果+
已经存在匹配子类型,为什么AspectJ的设计不一致?
方法执行被捕获,因为您正在拦截基 class 中定义的方法。当在 subclass 中被覆盖时,它仍然会被匹配。切入点 不会 匹配 subclass 中定义的任何方法。
让我重命名您的 classes 以使代码更具可读性,并将其变成 MCVE:
基础class:
package de.scrum_master.app;
public class Base {
public Base baseAction() {
return this;
}
}
Subclass 重写方法:
package de.scrum_master.app;
public class Sub extends Base {
@Override
public Sub baseAction() {
return this;
}
public Sub subAction() {
return this;
}
}
请注意,我在 subclass 中添加了另一种方法,它不包含在基础 class.
中驱动申请:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new Base().baseAction();
System.out.println("-----------------");
new Sub().baseAction();
System.out.println("-----------------");
new Sub().subAction();
}
}
看点:
package de.scrum_master.app;
import de.scrum_master.app.Base;
public aspect MyAspect {
before() : execution(Base Base.*(..)) {
System.out.println("Base Base.*(..) -> " + thisJoinPoint);
}
before() : execution(Base+ Base.*(..)) {
System.out.println("Base+ Base.*(..) -> " + thisJoinPoint);
}
before() : execution(Base Base+.*(..)) {
System.out.println("Base Base+.*(..) -> " + thisJoinPoint);
}
before() : execution(Base+ Base+.*(..)) {
System.out.println("Base+ Base+.*(..) -> " + thisJoinPoint);
}
}
控制台日志:
Base Base.*(..) -> execution(Base de.scrum_master.app.Base.baseAction())
Base+ Base.*(..) -> execution(Base de.scrum_master.app.Base.baseAction())
Base Base+.*(..) -> execution(Base de.scrum_master.app.Base.baseAction())
Base+ Base+.*(..) -> execution(Base de.scrum_master.app.Base.baseAction())
-----------------
Base Base.*(..) -> execution(Sub de.scrum_master.app.Sub.baseAction())
Base+ Base.*(..) -> execution(Sub de.scrum_master.app.Sub.baseAction())
Base Base+.*(..) -> execution(Sub de.scrum_master.app.Sub.baseAction())
Base+ Base+.*(..) -> execution(Sub de.scrum_master.app.Sub.baseAction())
-----------------
Base+ Base+.*(..) -> execution(Sub de.scrum_master.app.Sub.subAction())
如果您还在方法签名中的 class 名称中添加 +
,您能看出如何仅捕获 Sub Sub.subAction()
吗?这也是 +
的作用以及您需要它的原因的一个很好的例子。 return 类型和方法签名都需要 Base+
才能捕获 Sub Sub.subAction()
!