我想拦截给定类的任何子类的非注释方法的执行。
例如,假设我有课Base
:
public class Base {
public void baseMethod() { //shouldn't be intercepted
// do whatever...
}
}
最终,某人延伸Base
。无论新类名是什么,都不应截取带有注释@LeaveItAlone
的方法。子类的所有其他方法都应该。
public class Sub extends Base {
public void interceptedMethod1() {
// ...
}
public void interceptedMethod2() {
// ...
}
@LeaveItAlone
public void NOTinterceptedMethod1() {
// ...
}
@LeaveItAlone
public void NOTinterceptedMethod2() {
// ...
}
我想象的是:
pointcut sub_nonannotated() : !execution(@LeaveItAlone * Base+.*(..));
但我确定上述内容是错误的。
附带问题:我如何具体拦截子类的构造函数?
答案 0 :(得分:4)
实际上我只是尝试了它,你显然几乎是正确的。这对我有用:
package com.snaphop.ats.util;
public aspect Blah {
pointcut sub_nonannotated() : !execution(@LeaveItAlone * Base+.*(..));
pointcut sub() : execution(* Base+.*(..));
pointcut notBase() : ! execution(* Base.*(..));
pointcut cons() : execution(public Base+.new(..)) && ! execution(public Base.new(..));
//advice sub class methods but not annotation or parent
Object around() : sub_nonannotated() && sub() && notBase() {
return proceed();
}
//Advice subclass constructors but not Base's constructor
Object around() : cons() {
return proceed();
}
}
答案 1 :(得分:0)
Adam Gent的解决方案过于复杂。这个切入点更简单明了:
execution(!@LeaveItAlone * Base+.*(..))
或者,或许,你可能更喜欢(品味):
execution(* Base+.*(..)) && !@annotation(LeaveItAlone)
P.S。:这只涉及方法,而不是构造函数,这是你在第一句话中要求的。我还包括Base
本身的方法,而不仅仅是子类,这可能是有意义的。如果你想要一个更复杂的东西,你仍然可以将我的解决方案与Adam的元素结合起来。