当前位置: 首页 > 知识库问答 >
问题:

Spring AOP:捕获了带有参数注释的接口方法,但注释不存在

漆雕誉
2023-03-14

我使用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.
    }
}

现在我希望任何使用@AwesomeAnnoting注释的参数的方法都应该被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() {}
}

但是,当我尝试查找参数注释时,我没有得到任何注释。如上所述,annotationMatrix为空。

所以我的问题是:

  1. 为什么annotationMatrix为空?可能是因为参数注释不是从接口继承

共有2个答案

公良泰宁
2023-03-14

您的问题的答案:

>

  • 参数注释不是从接口继承到实现方法。事实上,注释几乎从不被继承,只从类(而不是接口!)如果注释类型本身由继承的注释,则要生成子类,请参阅JDK API文档。更新:因为我之前已经多次回答了这个问题,所以我刚刚记录了这个问题,以及使用AspectJ模拟接口和方法的注释继承的解决方法。

    因为在编译或编织期间,AeyJ可以将您的切入点与接口方法相匹配,从而看到注释。

    您可以通过在接口实现中向参数添加注释来解决这种情况,例如:

    @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()
    

  • 奚光霁
    2023-03-14

    我的一个参数注释也面临这个问题。我可以通过确保参数注释定义将RetentionPolicy作为运行时,将Target作为参数来解决这个问题

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    public @interface Param {
    
        public String name();
    
    }
    
     类似资料:
    • 我有一个可用于注释的方面: 连接点: 我可以在具有

    • 我创建了自定义注释。我将用它来注释方法参数。 我在这里找到了一些示例代码,展示了如何创建针对自定义注释的切入点。 所以现在,我创建了一个带切入点的方面。但是我不知道如何获得用注释的参数值。

    • 我对这条规则有两个问题: > 在注释函数的最后一个参数中,我找不到正确的语法来将文本字符串与捕获组变量组合在一起。上面的“操作”字段导致以下异常: ParseException:在第34行第72列遇到“+”“+”。我期待其中之一:“)”...“,”... 显然,当我使用“+”将字符串追加到一起时,最后一个参数没有正确地强制转换为字符串。 将最后一个参数中的字符串组合到注释函数中的正确方法是什么?

    • 我创建了一个简单应用程序,它使用Spring boot和JPA/Hibernate将消息保存在postgresql数据库中。所有的包Controller/Service/Repository都在一个子包中。 但我得到一个错误:spring boot无法识别包DAO中的存储库接口。 我有另一个项目,所有工作都不使用@enablejparepositories,但在这个项目(相同的结构)中,我遇到了这

    • 我试图让aspectj拦截带注释的方法: 我删除了!为了简洁起见,在(InterceptMeAspect)内,但它并没有拦截太多。如果我删除注释约束(在(@InterceptMe*)内),它可以工作,但会拦截所有内容,这会造成一个大问题。 输出字节码似乎有完整的注释,所以我希望注释标准匹配。我正在或试图进行编译时编织。这很重要,因为我有另一个方面确实使用上面相同的方法工作。我怀疑该方面正在搞乱这个

    • 我在想一个一般的请求映射问题。在不选择任何特定MVC框架的情况下,将基于注释的请求映射与简单的参数检查器映射进行比较,哪一个更好? 假设我想创建一个web服务,它应该处理例如“添加”和“删除”操作。 使用注释,它看起来像这样: 使用参数,它将如下所示: 在第二个示例中,假设Operation对象是从JSON对象构建的。我们的想法是,我们只有一个通用的操作,它有一个类型参数,我们总是调用相同的请求(