当前位置: 首页 > 知识库问答 >
问题:

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

狄信然
2023-03-14

我试图在切入点中检测用注释@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个答案

牧熙云
2023-03-14

只要方面和注释在同一个包中,它就可以工作。否则,该特性将导致编译器错误,例如:

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))

除了您希望看到的方法执行之外,还包括静态类初始化、构造函数执行和构造函数(预)初始化。

那么你需要做什么呢?

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

下面是一个完整的例子:

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))

附言:切入点也可以这样写,依我看,这有点难读:

@Pointcut("execution (* (@de.scrum_master.app.NFCDisable *).*(..))")
 类似资料:
  • 我正在使用Spring的AspectJ和CGLIB代理。我有一个定义如下的方面,我希望它在具体的类上为公共方法提供建议,这些类是用批注“validatormethod”批注的:

  • add:如果我将方法存根添加到Fragment2中,就可以开始使用next annotation,但这是一个非常难看的解决方案 解决方案:多亏了@Kriegaex,我找到了解决方案:

  • 问题内容: 我想用指定的注释(例如@Monitor)监视所有类的所有公共方法(注意:注释在类级别)。可能的切入点是什么?注意:我正在使用@AspectJ样式的Spring AOP。 问题答案: 你应该将类​​型切入点与方法切入点结合使用。 这些切入点将在标记为@Monitor的类中查找所有公共方法: 为结合了前两者的最后一个切入点提供建议,你就完成了!

  • 服务实现 但是,如果我将注释移动到公共接口方法实现,我的方面就会被触发。我应该如何定义我的切入点或配置我的方面来使我的原始用例工作?

  • 对于用@X注释的类中的方法或用@X注释的方法,我需要一个切入点。我还需要注释对象。如果类和方法都被注释,我更喜欢将方法注释作为参数。 我尝试了以下操作,这会产生“绑定不一致”的警告。(为什么不直接将其设置为null?) 以下内容创建了“穿过切入点中的“||”的参数x的不明确绑定”警告。(在我看来,这不一定有意义:为什么不绑定第一个短路评估?) 如果存在类和方法注释,则将前面的尝试拆分为两个,自然会

  • 问题内容: 我正在寻找一个切入点,该切入点与类中具有特定注释的子类的类中的方法执行相匹配。出色的AspectJ备忘单帮助我创建了以下切入点: 这与带有@AnnotationToMatch的类A的所有方法调用匹配,但与扩展了A的类B的方法匹配。我如何将两者匹配? 问题答案: