gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 10:00:44 27 4
gpt4 key购买 nike

我想创建一个仅对特定类型的返回值可用的注解。

例如这是我的注释。

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

}

我还有一个接口(interface):

public interface MyInterface {
String generateKey();
}

实现我的接口(interface)的示例类:

public class ExampleClass implements MyInterface {

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

所以在这些之后,如果返回类型未实现 MyInterface,我想以一种甚至不会编译的方式配置我的注释。

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

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

这不编译:

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

我想知道这是否可能。当然我可以检查参数是否在我的 Aspect 类中实现了这个接口(interface),但最好在我的库中有这种保护以便以防止滥用任何注释。

最佳答案

辅助分类器:

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

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";
}
}

不应编译的类:

这个类有一些注释的和一些非注释的方法。一个带注释的方法返回MyInterface 或其任何实现类。目标是编译失败。

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";
}
}

约定检查方面( native 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
  • 但返回类型不同于 MyInterface 或任何子类型或实现类。

这是 Eclipse 中的结果:

Eclipse: compilation error

当然,如果您从命令行或通过 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";
}

另请参阅此处的相关答案:

关于java - 创建仅适用于特定返回类型的自定义方法级别注释 [AOP],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57822694/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com