如何从ProceedingJoinPoint获取方法的注释值?

use*_*806 51 java spring spring-aop spring-3 java-ee-7

我有下面的注释.

MyAnnotation.java

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

}
Run Code Online (Sandbox Code Playgroud)

SomeAspect.java

public class SomeAspect{

 @Around("execution(public * *(..)) && @annotation(com.mycompany.MyAnnotation)")
    public Object procede(ProceedingJoinPoint call) throws Throwable {

  //Some logic

}

}
Run Code Online (Sandbox Code Playgroud)

SomeOther.java

public class SomeOther{

@MyAnnotation("ABC") 
public String someMethod(String name){


}


}
Run Code Online (Sandbox Code Playgroud)

在上面的类中我在@MyAnnotation中传递" ABC " .现在我如何在SomeAspect.java类的procede方法中访问" ABC "值?

谢谢!

Ren*_*ink 106

您可以从ProceedingJoinPoint获取签名,并且在方法调用的情况下,只需将其转换为MethodSignature.

@Around("execution(public * *(..)) && @annotation(com.mycompany.MyAnnotation)")
public Object procede(ProceedingJoinPoint call) throws Throwable {
    MethodSignature signature = (MethodSignature) call.getSignature();
    Method method = signature.getMethod();

    MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
}
Run Code Online (Sandbox Code Playgroud)

但是您应该首先添加注释属性.您的示例代码没有,例如

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();
}
Run Code Online (Sandbox Code Playgroud)

然后你可以访问它

MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
String value = myAnnotation.value();
Run Code Online (Sandbox Code Playgroud)

编辑

如果我在班级有@MyAnnotation("ABC"),如何获得价值?

A Class也是一个AnnotatedElement,所以你可以像从a那样得到它Method.例如,可以使用获得方法的声明类的注释

 Method method = ...;
 Class<?> declaringClass = method.getDeclaringClass();
 MyAnnotation myAnnotation = declaringClass.getAnnotation(MyAnnotation.class)
Run Code Online (Sandbox Code Playgroud)

正如你使用弹簧,你可能也想使用弹簧AnnotationUtils.findAnnotation(..).它会像spring一样搜索注释.例如,还要查看超类和接口方法等.

 MyAnnotation foundAnnotation = AnnotationUtils.findAnnotation(method, MyAnnotation.class);
Run Code Online (Sandbox Code Playgroud)


Hea*_*ren 16

实际上我认为我们可以通过value另一种方式获得,而不仅仅是从ProceedingJoinPoint,这肯定需要我们使用reflection.

请直接使用注释进行如下尝试:添加com.mycompany.MyAnnotation yourAnnotation您的in advice params@annotation(yourAnnotation)in @Around.

@Around("execution(public * *(..)) && @annotation(yourAnnotation)")
public Object procede(ProceedingJoinPoint pjp, com.mycompany.MyAnnotation yourAnnotation) {
    ...
    yourAnnotation.value(); // get your annotation value directly;
    ...
}
Run Code Online (Sandbox Code Playgroud)

com.mycompany.MyAnnotation 在建议参数中只是像那样工作

@Around("execution(public * *(..)) && @annotation(com.mycompany.MyAnnotation)")
Run Code Online (Sandbox Code Playgroud)

yourAnnotation可以是有效的变量名,因为MyAnnotation在params中已经指出了它应该是哪个注释.这里yourAnnotation仅用于检索注释实例.

如果你想传递更多参数,你可以试试args().

有关详细信息,请查看其官方文档.对于注释值,您只需搜索即可@Auditable.

  • 我认为这应该是一个可以接受的答案,因为它更干净,而且记录在案:https://docs.spring.io/spring/docs/4.3.15.RELEASE/spring-framework-reference/html/aop.html (3认同)