Spring 的 AspectJ:拦截的方法丢失了它们的参数注释

AspectJ with Spring : intercepted methods lose their parameters annotations

我最近将带有 aspectJ 和 spring-aop 的 AOP 添加到我现有的 spring 项目中。目标是实际拦截控制器调用以修改它们发回的响应,以便将一些值绑定到此响应我不想手动添加到我的每个控制器,例如实际令牌的到期日期由最终用户使用(在任何情况下我什至无法在我的控制器中展示)。在我开始单元测试之前,我实际上设法让它工作:

在我的单元测试中,我使用来自 java 的反射功能直接调用我的控制器方法,然后复制通常的过程(调用过滤器链、预处理程序和 post 处理程序,以及控制器方法本身当注释@Valid 出现在我的一个参数上时,首先使用 spring 验证器手动验证。所有这些过程工作正常并正确执行)。问题是,现在控制器方法被 spring-aop 拦截,它被称为来自创建的代理控制器,并且我所有的参数注释都消失了。这是一个控制器示例:

@Override
public ResponseEntity<Object> editPassword(@Valid @RequestBody PasswordEditForm passwordEditForm, HttpServletRequest request) {
    return factorizedUserBaseController.editPassword(passwordEditForm, request, User.class);
}

参数 PasswordEditForm 有注释 @Valid 所以在我的测试用例中它在任何其他步骤之前首先被验证,但是现在当我仔细检查它时,@Valid 注释不存在于代理方法中,因此参数没有得到验证,关于如何解决这个问题并使我的参数注释从我的测试角度仍然可以理解的任何线索?

注意:当 运行 通过 mvn spring-boot:运行 连接 spring 时,带有 @Valid 注释的参数得到正确验证,然后出现我的错误处理程序方法正确。

问题已解决:从其他几个 Whosebug 帖子我了解到 CGLIB(Spring 使用的 aop 代理库)不支持注释。 (参见 Retain annotations on CGLIB proxies?)。但我的问题不在这里,我确实确定我正在使用控制器 class 本身(我编码的那个)找到方法,但我错了,我将控制器实例作为参数提供给我代码的其他一些部分反过来会使用这个控制器 class 来找到当然不起作用的方法,因为多亏了 Spring 代理,它不再是我的控制器本身,而是一个代理class 扩展我自己的控制器 class。相反,我只需要替换 :

    Class<?> controllerClass = controllerInstanciationContainer
            .getController()
            .getClass();

    Class<?> controllerClass = controllerInstanciationContainer
            .getController()
            .getClass()
            .getSuperclass();