创建仅适用于特定 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";
}
也可以在这里查看我的相关答案:
我想创建一个仅适用于特定类型 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";
}
也可以在这里查看我的相关答案: