我在弹簧靴中遇到了问题。我试图给一些RestControllers提供额外的功能,我试图通过一些自定义注释来实现它。这是一个例子。
我的注释:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
String someArg();
}
我的方面:
@Aspect
@Component
public class MyAspect {
@Around(
value = "@annotation(MyCustomAnnotation)",
argNames = "proceedingJoinPoint,someArg"
)
public Object addMyLogic(ProceedingJoinPoint proceedingJoinPoint, String someArg)
throws Throwable
{
System.out.println(someArg);
return proceedingJoinPoint.proceed();
}
}
我的方法:
@MyCustomAnnotation(someArg = "something")
@GetMapping("/whatever/route")
public SomeCustomResponse endpointAction(@RequestParam Long someId) {
SomeCustomResult result = someActionDoesNotMatter(someId);
return new SomeCustomResponse(result);
}
主要基于文档(https://docs.spring.io/spring/docs/3.0.3.RELEASE/spring-framework-reference/html/aop.html - 7.2.4.6建议参数)我很确定,它应该有效。
我在这里,因为它没有...
让我疯狂的是,甚至Intellij,当试图帮助argNames(空字符串 - >红色下划线 - > alt +输入 - >正确的argNames属性)给我这个,并保持红色..
根据文档,甚至不需要继续执行StartInPoint(如果没有它也无法工作):"如果第一个参数是JoinPoint,则ProceedingJoinPoint ......"
使用当前设置,它会显示" Unbound切入点参数' someArg'"
此时,我还应该注意,如果没有args,它工作正常。
我实际上有两个问题:
为什么这不起作用? (这很明显)
如果我想为某些控制器提供一些额外的功能,我想从外部对其进行参数化,是否是春季启动时的正确模式? (使用python,使用装饰器很容易做到这一点 - 我不太确定,我没有被类似的语法误导)
一个例子(上面的例子非常简单):
我想创建一个@LogEndpointCall注释,稍后路由的开发人员可以将它放在他正在开发的端点上
...但是,如果他可以添加一个字符串(或更可能是一个枚举)作为参数,那就太好了
@LogEndpointCall(EndpointCallLogEnum.NotVeryImportantCallWhoCares)
或
@LogEndpointCall(EndpointCallLogEnum.PrettySensitiveCallCheckItALot)
以便触发相同的逻辑,但使用不同的参数 - >并且将保存到不同的目的地。
答案 0 :(得分:2)
您无法将注释属性直接绑定到advice参数。只需绑定注释本身并正常访问其参数:
sys.database_files
它将使用Spring AOP打印出类似的内容
@Around("@annotation(myCustomAnnotation)")
public Object addMyLogic(
ProceedingJoinPoint thisJoinPoint,
MyCustomAnnotation myCustomAnnotation
)
throws Throwable
{
System.out.println(thisJoinPoint + " -> " + myCustomAnnotation.someArg());
return thisJoinPoint.proceed();
}
和AspectJ这样的东西(因为AJ也知道调用连接点,而不仅仅是执行)
execution(SomeCustomResponse de.scrum_master.app.Application.endpointAction(Long)) -> something
答案 1 :(得分:1)
如果你希望你的方法拦截考虑args的方法,你必须明确提到你的切入点表达式,让它在这里工作是你应该做的:
@Around(
value = "@annotation(MyCustomAnnotation) && args(someArg)",
argNames = "someArg")
请注意我添加&& args(someArg),您可以根据需要添加任意数量的参数,在argNames中可以省略 proceedingJoinPoint 。