AspectJ:如何选择给定类的子类的非注释方法的执行?

时间:2013-04-11 15:28:39

标签: aspectj java aop

我想拦截给定类的任何子类的非注释方法的执行。

例如,假设我有课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+.*(..));

但我确定上述内容是错误的。

附带问题:我如何具体拦截子类的构造函数?

2 个答案:

答案 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的元素结合起来。