创建仅适用于特定 return 类型的自定义方法级别注释 [AOP]

Create custom method level annotation only available to specific return types [AOP]

我想创建一个仅适用于特定类型 return 值的注释。

例如这是我的注释。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MyAnnotation {

}

我也有接口:

public interface MyInterface {
    String generateKey();
}

实现我的接口的示例class:

public class ExampleClass implements MyInterface {

@Override
public String generateKey() {
   return "Whatever";
    }
}

所以在这些之后,我想以一种方式配置我的注释,如果 return 类型没有实现 它甚至不会编译 MyInterface.

在这种情况下,我希望它可以正常编译:

@MyAnnotation
public ExampleClass anExampleMethod() {
    return new ExampleClass();
}

这不能编译:

@MyAnnotation
public String anotherMethod() {
    return "Whatever";
}

我想知道这是否可行。当然我可以检查参数是否在我的方面实现了这个接口class但是最好有我的库中的这种保护是为了防止滥用任何注释。

帮手classer:

这些直接来自您的示例,仅包含包名称和导入。

package de.scrum_master.app;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(METHOD)
public @interface MyAnnotation {}
package de.scrum_master.app;

public interface MyInterface {
  String generateKey();
}
package de.scrum_master.app;

public class ExampleClass implements MyInterface {
  @Override
  public String generateKey() {
    return "Whatever";
  }
}

Class 不应该编译:

此 class 有一些带注释的方法和一些未带注释的方法。一个带注释的方法 not return MyInterface 或其任何实现 classes。目标是编译失败。

package de.scrum_master.app;

public class Application {
  @MyAnnotation
  public MyInterface annotatedMethodReturningInterface(int number) {
    return new ExampleClass();
  }

  @MyAnnotation
  public ExampleClass annotatedMethodReturningImplementingClass() {
    return new ExampleClass();
  }

  @MyAnnotation
  public String annotatedMethodReturningSomethingElse() {
    // This one should not compile!
    return "Whatever";
  }

  public MyInterface nonAnnotatedMethodReturningInterface(int number) {
    return new ExampleClass();
  }

  public ExampleClass nonAnnotatedMethodReturningImplementingClass() {
    return new ExampleClass();
  }

  public String nonAnnotatedMethodReturningSomethingElse() {
    return "Whatever";
  }
}

约定检查方面(本机 AspectJ 语法):

package de.scrum_master.aspect;

import de.scrum_master.app.MyAnnotation;
import de.scrum_master.app.MyInterface;

public aspect AnnotationCheckerAspect {
  declare error :
    @annotation(MyAnnotation) && execution(* *(..)) && !execution(MyInterface+ *(..)) :
    "Method annotated with @MyAnnotation must return MyInterface type";
}

这方面检查

  • 所有方法执行
  • 其中方法有 @MyAnnotation
  • 但 return 类型不同于 MyInterface 或任何子类型或实现 class.

这是 Eclipse 中的结果:

当然,如果您从命令行或通过 AspectJ Maven 插件或类似插件编译,编译错误是一样的。

如果您不喜欢原生语法(我更喜欢它,但出于某些难以理解的原因,其他人似乎更喜欢@AspectJ 风格):

约定检查方面(基于注解的@AspectJ 语法):

package de.scrum_master.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareError;

@Aspect
public class AnnotationCheckerAspect {
  @DeclareError(
    "@annotation(de.scrum_master.app.MyAnnotation) && " +
    "execution(* *(..)) && " +
    "!execution(de.scrum_master.app.MyInterface+ *(..))"
  )
  static final String wrongSignatureError =
  "Method annotated with @MyAnnotation must return MyInterface type";
}

也可以在这里查看我的相关答案: