Spring AOP pointcut for annotated argument

[亡魂溺海] 提交于 2020-02-19 09:27:40

问题


Say I have a method like so:

public void method(@CustomAnnotation("value") String argument)

Is there a pointcut expression that could select all methods with arguments annotated with @CustomAnnotation? If so is there a way I could get access go the "value" argument?


回答1:


On selecting your arguments :

@Before("execution(* *(@CustomAnnotation (*)))")
public void advice() {
System.out.println("hello");
}

ref : http://forum.springsource.org/archive/index.php/t-61308.html

On getting the annotation param :

MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Annotation[][] methodAnnotations = method.getParameterAnnotations();

Will get you the annotations which you can iterate and use instanceof to find your bound annotation. I know thats hacky but afaik this is the only way supported currently.




回答2:


To match 1..N annotated arguments regardless of their position use

@Before("execution(* *(@CustomAnnotation (*), ..)) || " +
        "execution(* *(.., @CustomAnnotation (*), ..)) || " +                         
        "execution(* *(.., @CustomAnnotation (*)))")
public void advice(int arg1, @CustomAnnotation("val") Object arg2) { ... }



回答3:


Just to complete the last answer:

@Before(value="execution(* *(@CustomAnnotation (*), ..)) && args(input, ..)")
public void inspect(JoinPoint jp, Object input) {
        LOGGER.info(">>> inspecting "+input+" on "+jp.getTarget()+", "+jp.getSignature());
}

will match a method where (one of) the argument of the method is annotated with @CustomAnnotation, for example:

service.doJob(@CustomAnnotation Pojo arg0, String arg1);

In contrast to

@Before(value="execution(* *(@CustomAnnotation *, ..)) && args(input, ..)")
public void inspect(JoinPoint jp, Object input) {
            LOGGER.info(">>> inspecting "+input+" on "+jp.getTarget()+", "+jp.getSignature());
    }

which will match methods where (one of) the argument has the annotation @CustomAnnotation, for example:

service.doJob(AnnotatedPojo arg0, String arg1);

where the pojo is declared as follows:

@CustomAnnotation
public class AnnotatedPojo {
}

All the difference lies in the @CustomAnnotation (*) vs. @CustomAnnotation * in the pointcut declaration.




回答4:


If you have more than one parameter in method you should use also two dots for mathing any number of parameters (zero or more)

@Before("execution(* *(@CustomAnnotation (*), ..))")
public void advice() {
    System.out.println("hello");
}



回答5:


From the Spring Docs:

@Before("@annotation(myAnnotation)")
public void audit(Auditable myAnnotation) {
  AuditCode code = auditable.value();
  // ...
}

Which works well for me, without any need to manipulate the method signature.

Note: If you're using a named pointcut, because pointcut names can be overloaded, you must supply matching (parameter name and order) signatures.

@Before("goodAdvise(myAnnotation)")
public void audit(Auditable myAnnotation) {
  String value = auditable.value();
  // ...
}

@Pointcut("@annotation(myAnnotation)")
public void goodAdvise(Auditable myAnnotation) { 
  //empty
}


来源:https://stackoverflow.com/questions/10247116/spring-aop-pointcut-for-annotated-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!