小编典典

Spring AOP切入“嵌套”注释

java

我需要定义一个切入点,该切入点触发使用自定义注释注释的spring服务的所有方法的执行。我想定义切入点的注释将在另一个注释上。

@Y
public @interface X {
}

然后该服务将被注释如下

@X
public Service1 {
}

我尝试使用以下切入点定义,但是仅当@Y在服务本身上时才有效,这意味着它看不到注释在@X上

@Around("@within(com.mypackage.Y)")

阅读 306

收藏
2020-11-26

共2个答案

小编典典

这不是Spring或AspectJ问题。在Java中,实现类,使用带注释的注释或重写方法的类永远不会继承接口,其他注释或方法上的注释。注释继承仅从类到子类有效,但前提是超类中使用的注释类型带有meta注释@Inherited

更新:
因为我之前已经回答过几次这个问题,所以我刚刚记录了该问题,并且还介绍了使用AspectJ进行接口和方法的仿真注释继承的变通方法

这里有一点证明,您想要的东西不起作用,因此也不能被一个方面利用:

package de.scrum_master.app;

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

@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface OuterAnnotation {}



package de.scrum_master.app;

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

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@OuterAnnotation
public @interface InnerAnnotation {}



package de.scrum_master.app;

import java.lang.annotation.Annotation;

@InnerAnnotation
public class Application {
    public static void main(String[] args) {
        for (Annotation annotation : Application.class.getAnnotations())
            System.out.println(annotation);
    }
}

控制台输出显示,JVM仅看到内部注释,而不是内部注释上使用的外部注释:

@de.scrum_master.app.InnerAnnotation()

更新: 布拉德利·汉迪(Bradley M
Handy)的回答引起了我的兴趣,我再次检查了它是否也适用于我的代码中所述的情况,确实如此。尽管我认为我对AspectJ知道很多,但我不知道这种类型的AspectJ语法。谢谢布拉德利。:-)这方面将工作:

package de.scrum_master.aspect;

import de.scrum_master.app.OuterAnnotation;

public aspect MetaAnnotationAspect {
  after() : within(@(@OuterAnnotation *) *) && execution(* *(..)) {
    System.out.println(thisJoinPoint);
  }
}

运行应用程序时的控制台日志:

@de.scrum_master.app.InnerAnnotation()
execution(void de.scrum_master.app.Application.main(String[]))
2020-11-26
小编典典

我在应用程序中有这个确切的需求。我找到了这个答案,但不满意无法完成。

经过更多搜索之后,我发现了用于AspectJ / Spring切入点表达式的备忘单。备忘单中的解决方案无法完全如广告中所述那样工作,但是我能够使其满足我的需要。

@Pointcut("within(@(@Annotation *) *)")
public void classAnnotatedWithNestedAnnotationOneLevelDeep() { }

我将此表达式与一个@within表达式组合在一起,@Annotation以获得想要的工作。

对于方法执行:

@Pointcut("execution(@(@com.someorg.SomeAnnotation *) * *(..))")
public void methodAnnotatedWithNestedAnnotationOneLevelDeep() { }

我将此表达式与@annotation仅用于的表达式相结合,@Annotation以获得我想为方法工作的东西。

2020-12-01