@AspectJ: 自定义注解的任何方法的切入点class
@AspectJ: Pointcut for any method of custom annotated class
我正在尝试在切入点中检测使用我的注释 @NFCDisable
.
注释的 class 的任何方法
@NFCDisable
public class MyClass {
//methods
}
我试过这个:
@Aspect
public class NFCAspect {
@Before("method()")
public void exec() {
//DO SOMETHING
}
@Pointcut("@within(NFCDisable) || @annotation(NFCDisable)")
public void method() {}
}
但是没用。我做错了什么?
谢谢。
只要你的方面和注释在同一个包中,它就可以工作。否则方面应该导致编译器错误,例如:
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))
这包括静态 class 初始化、构造函数执行和构造函数(预)初始化以及您希望看到的方法执行。
那么你需要做什么?
- 将切入点限制为真正只针对方法执行。
- 在基于注释的 AspectJ 语法中使用完全限定的 class 名称。
- 确保您的注释具有运行时保留范围。
这是一个完整的例子:
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 *).*(..))")
我正在尝试在切入点中检测使用我的注释 @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() {}
}
但是没用。我做错了什么?
谢谢。
只要你的方面和注释在同一个包中,它就可以工作。否则方面应该导致编译器错误,例如:
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))
这包括静态 class 初始化、构造函数执行和构造函数(预)初始化以及您希望看到的方法执行。
那么你需要做什么?
- 将切入点限制为真正只针对方法执行。
- 在基于注释的 AspectJ 语法中使用完全限定的 class 名称。
- 确保您的注释具有运行时保留范围。
这是一个完整的例子:
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 *).*(..))")