【问题标题】:How to validate custom AOP annotation如何验证自定义 AOP 注释
【发布时间】:2021-12-29 13:34:07
【问题描述】:

我有一个自定义注解如下

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Testable {
    int index();
}

我定义了一个 Aspect 来包裹实际的方法调用

@Aspect
@Component
public class TestableAspect {

    @Around("execution(public * *(..)) && @annotation(annotation)")
    public Object invokeAndLog(ProceedingJoinPoint joinPoint, Testable annotation) throws Throwable {
        return joinPoint.proceed();
    }
}

注解的用法如下图

@Testable(index = 1)
public void realMethod() {
    //some code here
}

到目前为止一切正常,我可以在 TestableAspect#invokeAndLog 中实现我的登录。

现在我需要验证 index 的值是否不大于 10 例如。

我可以在运行时通过如下更改方面实现来做到这一点

    @Around("execution(public * *(..)) && @annotation(annotation)")
    public Object invokeAndLog(ProceedingJoinPoint joinPoint, Testable annotation) throws Throwable {
        if(annotation.index() > 10){
          throw new IllegalStateException("blah");
        }
        return joinPoint.proceed();
    }

但这要求 API 至少被调用一次,而且效率不高。 有没有办法在启动 Spring Boot 应用程序时做到这一点?

【问题讨论】:

  • 你可以写一个注解处理器baeldung.com/java-annotation-processing-builder
  • 我想建议和西蒙一样。但是,如果注释可以在 OP 自己的构建过程控制之外的模块中使用,这可能不是一个选项。应该选择哪种方法还取决于实际检查注释条件的实际条件是静态的还是动态的。如果例如它总是> 10,然后可以在更中心的点进行验证。如果条件根据应用程序状态而变化,则切面实际上可能是更好的方法。

标签: java spring-boot aspectj spring-aop


【解决方案1】:

通常您会编写注释处理器或类加载器来验证注释。否则,您可以尝试如下使用反射:

new org.reflection.Reflections("your.desired.package")
  .getMethodsAnnotatedWith(Testable.class)
  .stream()
  .map(method -> AnnotationUtils.getAnnotation(method, Testable.class))
  .forEach(annotation -> {
    if (annotation.index() > 10)
      throw new IllegalStateException("blah");
  });

此类代码可以添加到任何类的静态块中,或者如果您想涉及 spring,只需将其添加到 start-up runner

这样的建议并不理想,并且需要扫描类路径但可以工作!

【讨论】:

  • 您的意思可能是getMethodsAnnotatedWith 而不是getFieldsAnnotatedWith,不是吗?感谢您的 Baeldung 链接,顺便说一句。这篇文章提供了一个很好的概述。
  • 是的,没错。不客气:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
相关资源
最近更新 更多