本文介绍了Spring AOP:捕获了带参数批注的接口方法,但不存在批注的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring AOP截取方法执行。

我有一个如下所示的界面:

public interface MyAwesomeService {
    public Response doThings(int id, @AwesomeAnnotation SomeClass instance);
}

接口的实现如下:

public class MyAwesomeServiceImpl implements MyAwesomeService {
    public Response doThings(int id, SomeClass instance) {
        // do something.
    }
}

现在,我希望任何具有@AwesomeAnnotation批注的参数的方法都应该由Spring AOP捕获。

所以我写了以下方面,有效

@Aspect
@Component
public class MyAwesomeAspect {
    @Around("myPointcut()")
    public Object doAwesomeStuff(final ProceedingJoinPoint proceedingJoinPoint) {
         final MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
         Annotation[][] annotationMatrix = methodSignature.getMethod().getParameterAnnotations();

         // annotationMatrix is empty.
    }

    @Pointcut("execution(public * *(.., @package.AwesomeAnnotation  (package.SomeClass), ..))")
    public void myPointcut() {}
}

然而,当我尝试查找参数注释时,我没有得到任何注释。如上所述,注解矩阵为空。

以下是我的问题:

  1. 为什么注解矩阵为空?可能是因为参数批注不是从接口继承的。
  2. 为什么我能够捕获方法执行。由于Spring AOP能够匹配切入点,Spring以某种方式能够看到方法的参数注释,但当我尝试使用methodSignature.getMethod().getParameterAnnotations()查看时,它不起作用。

推荐答案

您的问题的答案:

  1. 参数批注不是从接口继承到实现方法的。事实上,注释几乎从不继承,只是从类(而不是接口!)继承。若要在批注类型本身由@Inherited批注的情况下创建子类,请参阅JDK API documentation更新:因为我以前多次回答过此问题,所以我只是在Emulate annotation inheritance for interfaces and methods with AspectJ中记录了该问题和一个解决方法。

  2. 因为在编译或编织时,AspectJ可以将切入点与接口方法进行匹配,从而看到批注。

您可以通过向接口实现中的参数添加注释来解决此问题,例如:

@Override
public Response doThings(int id, @AwesomeAnnotation SomeClass instance) {
    // ...
}

然后使用这样的方面...

@Aspect
@Component
public class MyAwesomeAspect {
    @Pointcut("execution(public * *..MyAwesomeService.*(*, @*..AwesomeAnnotation (*), ..)) && args(*, instance, ..)")
    static void myPointcut(SomeClass instance) {}

    @Around("myPointcut(instance)")
    public Object doAwesomeStuff(Object instance, ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println(proceedingJoinPoint);
        System.out.println("  instance = " + instance);
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
         Annotation[][] annotationMatrix = methodSignature.getMethod().getParameterAnnotations();
         for (Annotation[] annotations : annotationMatrix) {
             for (Annotation annotation : annotations) {
                 System.out.println("  annotation = " + annotation);
             }
         }
         return proceedingJoinPoint.proceed();
    }
}

.您将看到类似以下内容的控制台日志:

execution(Response de.scrum_master.app.MyAwesomeServiceImpl.doThings(int, SomeClass))
  instance = de.scrum_master.app.SomeClass@23fc625e
  annotation = @de.scrum_master.app.AwesomeAnnotation()

这篇关于Spring AOP:捕获了带参数批注的接口方法,但不存在批注的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 06:14