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

Spring中的AspectJ:拦截的方法将丢失参数注释

许马鲁
2023-03-14

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

在我的单元测试中,我使用java中的反射特性直接调用我的控制器方法,然后复制通常的过程(调用过滤器链、前置处理程序和后置处理程序,以及控制器方法本身,当注释@valid出现在我的一个参数上时,首先使用spring validator手动验证。所有这些过程都工作良好,并得到正确执行)。问题是,现在控制器方法被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个答案

阎安邦
2023-03-14

问题解决了:从其他几篇stackoverflow文章中,我了解到CGLIB(Spring使用的aop代理库)不支持注释。(请参见保留CGLIB代理上的注释?)。但我的问题不在这里,我确实是在使用控制器类本身(我编码的那个)找到方法,但我错的是,我将控制器实例作为参数赋予了代码的其他部分,这些部分反过来会使用这个控制器类来找到方法,而这个方法当然不起作用,因为多亏了Spring代理,它不再是我的控制器本身,而是扩展我自己的控制器类的代理类。相反,我只需要替换:

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

    Class<?> controllerClass = controllerInstanciationContainer
            .getController()
            .getClass()
            .getSuperclass();
 类似资料:
  • 我正在使用AeyJ拦截一个名为的方法。为此,我使用了我自己指定的(标记)注释。这就是类的样子: 截取截取注释的方面: 然而,我的方面是基于带注释的参数进行拦截。但我希望方面能够拦截参数t包含的特定值的方法请求。 例如,如果t==“t1”,则必须截取该方法,否则不能截取。 我想知道是否可以在AeyJ(与Spring AOP结合使用)中做到这一点。

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

  • 所以我有一个自定义注释 我想使用它将方面编织到方法中(AspectJ,<代码>@注释(截取) )。 其思想是,当我直接注释方法截取时,我将方面编织入其中——这一部分起作用——或者如果我注释类,则应将方面编织入其所有(公共)方法中——这一部分不起作用。 此外,如果我对一个类及其一个方法进行注释,则方面应该只被编织一次,方法级注释将覆盖类级注释。 本质上,我想要一个“如果有类级注释,但只有在还没有方法

  • 我想拦截所有用特定注释注释类的构造函数调用。 我有这样一个方面: 还有一个例子: 现在,如果我更改方面并删除@注释过滤器,那么我看到aspectj正在拦截调用。此外,如果我创建一个默认构造函数,然后用注释对其进行注释,它也可以工作。 但是,我希望注释存在于类中,这样如果我有1个构造函数或10个,它们都将被相同地拦截(我只需要将其放在类中)。

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