AspectJ with Spring:截获的方法会丢失参数注释

时间:2017-09-30 09:29:46

标签: java annotations aspectj spring-aop

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

在我的单元测试中,我使用java中的反射功能直接调用我的控制器方法,然后复制常规过程(调用过滤器链,预处理程序和后处理程序,以及控制器方法本身,首先使用弹簧验证器手动验证注释) @Valid存在于我的一个参数上。所有这些过程都可以正常工作并正确执行)。问题是,现在控制器方法被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:run运行spring时,带有@Valid注释的参数会被正确验证,然后正确地转到我的错误处理程序方法。

1 个答案:

答案 0 :(得分:0)

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

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

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