Spring boot Spring AOP-带参数的注释

Spring boot Spring AOP-带参数的注释,spring-boot,spring-aop,spring-annotations,Spring Boot,Spring Aop,Spring Annotations,我的弹簧靴出了问题。我试图为一些restcontroller提供额外的功能,并试图通过一些自定义注释来实现它。这里有一个例子 我的注解: @Target(ElementType.METHOD) @保留(RetentionPolicy.RUNTIME) public@interface MyCustomAnnotation{ 字符串someArg(); } 我的方面: @方面 @组成部分 公共类MyAspect{ @周围( value=“@注释(MyCustomAnnotation)”, arg

我的弹簧靴出了问题。我试图为一些restcontroller提供额外的功能,并试图通过一些自定义注释来实现它。这里有一个例子

我的注解:

@Target(ElementType.METHOD)
@保留(RetentionPolicy.RUNTIME)
public@interface MyCustomAnnotation{
字符串someArg();
}
我的方面:

@方面
@组成部分
公共类MyAspect{
@周围(
value=“@注释(MyCustomAnnotation)”,
argNames=“proceedingJoinPoint,someArg”
)
公共对象addMyLogic(ProceedingJoinPoint ProceedingJoinPoint,字符串someArg)
扔掉的
{
System.out.println(someArg);
return proceedingJoinPoint.procedure();
}
}
我的方法:

@MyCustomAnnotation(someArg=“something”)
@GetMapping(“/whatever/route”)
公共SomeCustomResponse端点操作(@RequestParam Long someId){
SomeCustomResult结果=someActionDoesNotMatter(someId);
返回新的响应(结果);
}
主要基于文档(-7.2.4.6建议参数),我非常确定,它应该可以工作

我在这里,因为它不

让我疯狂的是,即使是Intellij,当试图帮助使用argNames(空字符串->红色下划线->alt+enter->正确的argNames属性)时,也会给我这个,并保持红色

根据文档,甚至不需要proceedingJoinPoint(没有它也无法工作):“如果第一个参数是JoinPoint,则proceedingJoinPoint…”

在当前设置中,它显示“未绑定切入点参数'someArg'”

在这一点上,我还应该注意到,没有args,它工作得很好

实际上,我有两个问题:

  • 为什么这不起作用?(这很明显)

  • 如果我想给一些控制器提供一些额外的功能,并且我想从外部对其进行参数化,那么它是spring boot中的正确模式吗?(对于python,使用decorator很容易做到这一点——我不太确定,我没有被类似的语法误导)

  • 一个例子(上面的例子非常简单):

    我想创建一个@LogEndpointCall注释,路由的开发人员可以稍后将它放在他正在开发的端点上

    …但是,如果他可以添加一个字符串(或者更可能是一个枚举)作为参数,那就太好了

    @LogEndpointCall(EndpointCallLogEnum.notveryiimportantcallwhocares)
    

    @LogEndpointCall(EndpointCallLogEnum.PrettySensitiveCallCheckItALot)
    

    因此,将触发相同的逻辑,但使用不同的参数->并将其保存到不同的目标。

    如果您希望方法拦截考虑参数的方法,您必须明确指出,在切入点表达式中,要使其工作,您应该做的是:

    @Around(
    value = "@annotation(MyCustomAnnotation) && args(someArg)",
    argNames = "someArg")
    

    请注意,我添加了和&args(someArg),您可以添加任意数量的参数,在argNames中可以省略proceedingJoinPoint

    不能直接将注释属性绑定到通知参数。只需绑定注释本身并正常访问其参数:

    周围(“@注释(myCustomAnnotation)”) 公共对象addMyLogic( 处理连接点此连接点, MyCustomAnnotation MyCustomAnnotation ) 扔掉的 { System.out.println(thisJoinPoint+“->”+myCustomAnnotation.someArg()); 返回此连接点。继续(); } 它将使用Spring AOP打印类似这样的内容

    execution(SomeCustomResponse de.scrum_master.app.Application.endpointAction(Long))->something
    
    AspectJ也是这样(因为AJ也知道调用连接点,而不仅仅是执行)

    call(SomeCustomResponse de.scrum_master.app.Application.endpointAction(Long))->something
    执行(SomeCustomResponse de.scrum_master.app.Application.endpointAction(Long))->something
    
    这个答案是错误的。问题不在于绑定方法参数,而在于访问绑定注释的参数。我在使用完整的包名时遇到了问题。我正在尝试:@Around(@annotation(com.xyz.myCustomAnnotation)”)。当我需要输入注释的名称时,如上面的答案所示:@about(@annotation(myCustomAnnotation)”)。上面的答案帮助我访问了注释及其参数。如果不将注释绑定到方法参数,则必须使用完整的包名,如果绑定到方法参数,则不能使用完整的包名。这是合乎逻辑的,因为如果有参数,可以很容易地确定类型。如果没有,则需要准确地指定类型,因为无法从导入的类推断出该类型。