通过自定义注释基于参数名称获取参数值

时间:2019-11-26 15:33:59

标签: java spring

我正在使用自定义批注根据其名称获取参数的值。 该实现基于此处的过去示例,但出现以下错误。 请问我在做错什么事吗?谢谢。

当类ExpressionEvaluator调用方法condition()时抛出错误。

错误如下:

  

EL1027E:不支持索引到类型'ExpressionRootObject'   org.springframework.expression.spel.SpelEvaluationException:EL1027E:   不支持索引到“ ExpressionRootObject”类型

自定义注释

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnot {
    String name();
    String countryCode() default "example";
    String[] requestKeys();
}

根对象

public class ExpressionRootObject {
    private final Object object;

    private final Object[] args;

    public ExpressionRootObject(Object object, Object[] args) {
        this.object = object;
        this.args = args;
    }

    public Object getObject() {
        return object;
    }

    public Object[] getArgs() {
        return args;
    }
}

表达评估器

public class ExpressionEvaluator<T> extends CachedExpressionEvaluator {

    // shared param discoverer since it caches data internally
    private final ParameterNameDiscoverer paramNameDiscoverer = new DefaultParameterNameDiscoverer();

    private final Map<ExpressionKey, Expression> conditionCache = new ConcurrentHashMap<>(64);

    private final Map<AnnotatedElementKey, Method> targetMethodCache = new ConcurrentHashMap<>(64);

    /**
     * Create the suitable {@link EvaluationContext} for the specified event handling
     * on the specified method.
     */
    public EvaluationContext createEvaluationContext(Object object, Class<?> targetClass, Method method, Object[] args) {

        Method targetMethod = getTargetMethod(targetClass, method);
        ExpressionRootObject root = new ExpressionRootObject(object, args);
        return new MethodBasedEvaluationContext(root, targetMethod, args, this.paramNameDiscoverer);
    }

    /**
     * Specify if the condition defined by the specified expression matches.
     */
    public T condition(String conditionExpression, AnnotatedElementKey elementKey, EvaluationContext evalContext, Class<T> clazz) {
        // IT FAILS AT THIS CALL. 
        return getExpression(this.conditionCache, elementKey, conditionExpression).getValue(evalContext, clazz);
    }

    private Method getTargetMethod(Class<?> targetClass, Method method) {
        AnnotatedElementKey methodKey = new AnnotatedElementKey(method, targetClass);
        Method targetMethod = this.targetMethodCache.get(methodKey);
        if (targetMethod == null) {
            targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
            if (targetMethod == null) {
                targetMethod = method;
            }
            this.targetMethodCache.put(methodKey, targetMethod);
        }
        return targetMethod;
    }
}

尝试评估的方面

@Aspect
@Component
public class AspectMocking {

    @Around("@annotation(customAnnot)")
      public Object getMockedData(ProceedingJoinPoint pjp, CustomAnnot customAnnot) throws Throwable {


      try{
          //This is the call which eventually fails at the condition() method below.
          Long l = getValue(pjp, customAnnot.requestKeys()[0]);

      } catch(Exception e){
        //
      }
      return null;
    }

    private Long getValue(ProceedingJoinPoint joinPoint, String condition) {
      return getValue(joinPoint.getTarget(), joinPoint.getArgs(),
          joinPoint.getTarget().getClass(),
          ((MethodSignature) joinPoint.getSignature()).getMethod(), condition);
    }

    private Long getValue(Object object, Object[] args, Class clazz, Method method, String condition) {
      if (args == null) {
        return null;
      }
      EvaluationContext evaluationContext = evaluator.createEvaluationContext(object, clazz, method, args);
      AnnotatedElementKey methodKey = new AnnotatedElementKey(method, clazz);
      return evaluator.condition(condition, methodKey, evaluationContext, Long.class);
    }
}

我正在使用自定义注释注释以下方法:

@CustomAnnot(name = "APPLE", requestKeys = {"id", "label"})
  public Object get(long id, long label) {

  // some code
}

0 个答案:

没有答案