【问题标题】:How to get annotated method parameter and his annotation如何获取带注释的方法参数及其注释
【发布时间】:2014-05-30 08:31:38
【问题描述】:

在我的应用程序中,我的方法的参数由一些注释注释。现在我想编写 Aspect,使用来自注释属性的信息对注释参数进行一些预处理。例如方法:

public void doStuff(Object arg1, @SomeAnnotation CustomObject arg1, Object arg2){...}

方面:

@Before(...)
public void doPreprocessing(SomeAnnotation annotation, CustomObject customObject){...}

@Before 应该写什么?

编辑:

感谢大家。有我的解决方案:

@Before("execution(public * *(.., @SomeAnnotation (*), ..))")
public void checkRequiredRequestBody(JoinPoint joinPoint) {
    MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
    Annotation[][] annotations = methodSig.getMethod().getParameterAnnotations();
    Object[] args = joinPoint.getArgs();

    for (int i = 0; i < args.length; i++) {
        for (Annotation annotation : annotations[i]) {
            if (SomeAnnotation.class.isInstance(annotation)) {
                //... preprocessing
            }
        }
    }
}

【问题讨论】:

    标签: java spring aop aspectj


    【解决方案1】:

    你会这样做:

    @Before("execution(* com.foo.bar.*.doStuff(..)) && args(arg1, arg2)")
        public void logSomething(JoinPoint jp, CustomObject arg1, Object arg2) throws Throwable {
    
            MethodSignature methodSignature = (MethodSignature) jp.getSignature();
            Class<?> clazz = methodSignature.getDeclaringType();
            Method method = clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
            SomeAnnotation argumentAnnotation;
            for (Annotation ann : method.getParameterAnnotations()[0]) {
                if(SomeAnnotation.class.isInstance(ann)) {
                    argumentAnnotation = (SomeAnnotation) ann;
                    System.out.println(argumentAnnotation.value());
                }
            }
        }
    

    这是参数类型自定义注解:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.PARAMETER)
    public @interface SomeAnnotation {
        String value();
    }
    

    以及要拦截的方法:

    public void doStuff(@SomeAnnotation("xyz") CustomObject arg1, Object arg2) {
            System.out.println("do Stuff!");
        }
    

    你不能这样做

    @Before(...)
    public void doPreprocessing(SomeAnnotation annotation, CustomObject customObject){...}
    

    因为注解不是参数,在其中您只能引用参数。 您可以使用@args(annot) 完成您的方式,但这仅匹配放置在参数类型本身上的注释,而不是实际参数前面的注释。 @args(annot) 适用于这样的情况:

    @SomeAnnotation
    public class CustomObject {
    
    }
    

    【讨论】:

      【解决方案2】:

      这是一个应该有效的示例。 (我没有测试它,但它应该可以工作)

      @Before("execution(public * *(..))")
      public void preprocessAnnotations(JoinPoint joinPoint) throws Throwable {
      
              MethodSignature methodSig = (MethodSignature) joinPoint.getSignature();
              Annotation[][] annotations = methodSig.getMethod().getParameterAnnotations();
              if(annotations != null){
                  for(Annotation[] annotArr: annotations){
                      for(Annotation annot: annotArr){
                          if(annot instanceof Resource){
                              String nameOfResource = ((Resource)annot).name();
                          }
                      }
                  }
              }
      
      
      
      }
      

      这里我添加了javax.annotation.Resource的测试只是为了展示如何使用答案,但当然你应该用你需要处理的注释替换它

      【讨论】:

      • ProceedingJoinPoint 仅用于@Around 建议,JoinPoint 用于@Before
      • 嗯,回答应该是正确的。你说你没有测试它,但它的方式会引发错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-04
      • 1970-01-01
      • 2020-10-12
      • 1970-01-01
      相关资源
      最近更新 更多