Spring'AOP点切割'嵌套'注释 [英] Spring AOP point cut for 'nested' annotation

查看:117
本文介绍了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 {
}

然后该服务将注释为以下

and then the service would be annotated as following

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






更新: 布拉德利·M·汉迪(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. Thise 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天全站免登陆