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