用于“嵌套"注释的 Spring AOP 切入点 [英] Spring AOP point cut for 'nested' annotation

查看:29
本文介绍了用于“嵌套"注释的 Spring AOP 切入点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to define a point cut which triggers the execution on all methods of a spring service annotated with a custom annotation. The annotation I would like to define the point cut on will be on an other annotation.

@Y
public @interface X {
}

然后服务将被注释如下

@X
public Service1 {
} 

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

I tried with the following point cut definition but it only works when @Y is on the service itself, meaning that it doesn't see that the annotation is on @X

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

推荐答案

这不是 Spring 或 AspectJ 的问题.在 Java 中,接口上的注解、其他注解或方法永远不会通过实现类、使用注解注解或覆盖方法的类来继承.注解继承仅适用于从类到子类,但前提是超类中使用的注解类型带有元注解 @Inherited.

This is not a Spring or AspectJ problem. In Java, annotations on interfaces, other annotations or methods are never inherited by implementing classes, classes using annotated annotations or overriding methods. Annotation inheritance only works from classes onto subclasses, but only if the annotation type used in the superclass bears the meta annotation @Inherited.

更新:因为我之前已经多次回答过这个问题,所以我刚刚在 使用 AspectJ 模拟接口和方法的注解继承.

Update: Because I have answered this question several times before, I have just documented the problem and also a workaround in Emulate annotation inheritance for interfaces and methods with AspectJ.

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

Here is a little proof that what you want does not work and thus also cannot be utilised by an aspect:

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只看到内部注解,而不是内部注解上使用的外部注解:

The console output shows that only the inner annotation is seen by the JVM, not the outer one used on the inner annotation:

@de.scrum_master.app.InnerAnnotation()

<小时>

更新: 对 Bradley M Handy 的回答很感兴趣,我重新检查了它是否也适用于我的代码中描述的情况,确实如此.这种类型的 AspectJ 语法对我来说是未知的,尽管我认为我对 AspectJ 了解很多.所以谢谢,布拉德利.:-) 这方面会起作用:


Update: Intrigued by Bradley M Handy's answer, I re-checked if it would also work for the situation described in my code, and indeed it does. This type of AspectJ syntax was unknown to me, even though I think I know a lot about AspectJ. So thanks, Bradley. :-) This aspect would work:

package de.scrum_master.aspect;

import de.scrum_master.app.OuterAnnotation;

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

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

Console log when running the application:

@de.scrum_master.app.InnerAnnotation()
execution(void de.scrum_master.app.Application.main(String[]))

这篇关于用于“嵌套"注释的 Spring AOP 切入点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆