@AspectJ:自定义注释类的任何方法的切入点

时间:2015-03-11 09:41:30

标签: aspectj

我试图在切入点中检测使用我的注释@NFCDisable注释的类的任何方法。

@NFCDisable
public class MyClass { 
    //methods
}

我试过这个:

@Aspect
public class NFCAspect {

    @Before("method()")
    public void exec() {
        //DO SOMETHING
    }

    @Pointcut("@within(NFCDisable) || @annotation(NFCDisable)")
    public void method() {}
}

但它不起作用。我做错了什么?

感谢。

1 个答案:

答案 0 :(得分:3)

只要您的方面和注释位于同一个包中,它就可以正常工作。否则,方面应该导致编译器错误,例如:

Type referred to is not an annotation type: @missing@

但即使它们在同一个包中,切入点也会捕获太多的连接点,例如:

staticinitialization(de.scrum_master.app.MyClass.<clinit>)
preinitialization(de.scrum_master.app.MyClass())
initialization(de.scrum_master.app.MyClass())
execution(de.scrum_master.app.MyClass())
execution(void de.scrum_master.app.MyClass.foo())
execution(int de.scrum_master.app.MyClass.bar(String))

除了您想要查看的方法执行外,还包括静态类初始化,构造函数执行和构造函数(预)初始化。

那你需要做什么?

  • 将切入点限制为仅实现目标方法执行。
  • 在基于注释的AspectJ语法中使用完全限定的类名。
  • 确保您的注释具有运行时保留范围。

以下是一个完整的例子:

package de.scrum_master.app;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface NFCDisable {}
package de.scrum_master.app;

@NFCDisable
public class MyClass {
    public void foo() {}
    public int bar(String text) { return 11; }
}
package de.scrum_master.app;

public class Application {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.foo();
        myClass.bar("xxx");
    }
}
package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class NFCAspect {
    @Pointcut("execution (* *(..)) && @within(de.scrum_master.app.NFCDisable)")
    public void method() {}

    @Before("method()")
    public void exec(JoinPoint thisJoinPoint) {
        System.out.println(thisJoinPoint);
    }
}

控制台输出:

execution(void de.scrum_master.app.MyClass.foo())
execution(int de.scrum_master.app.MyClass.bar(String))

P.S。:切入点也可以这样写,这对IMO来说有点难:

@Pointcut("execution (* (@de.scrum_master.app.NFCDisable *).*(..))")