Spring SpEL选择错误的方法来调用

时间:2015-03-08 08:17:21

标签: spring openjdk spring-el

我试图评估以下SpEL表达式(Spring-expression版本3.1.1):

T(com.google.common.collect.Lists).newArrayList(#iterable)

其中#iterable的类型为java.lang.Iterable。 Google Guava com.google.common.collect.Lists(版本14.0)确实有一个方法 newArrayList(Iterable)但由于某种原因,SpEL选择调用另一种方法: newArrayList(Object [] )

我深入研究代码,发现问题与 org.springframework.expression.spel.support.ReflectiveMethodResolver 实现有关:它似乎对方法的排序方式很敏感:: java.lang.Class类的getMethods。 如果2个方法与调用匹配(在其中一个方法是varargs的情况下),将调用后一个方法(按顺序),而不是选择不是varargs的方法(更具体)。 看起来JDK并不能保证方法的排序顺序:不同的运行显示不同的顺序。

有没有办法克服这个问题?

1 个答案:

答案 0 :(得分:0)

您可以使用Spring EL的集合投影从iterable中选择所有并将其转换为list:

"#iterable.?[true]"

一个简单的测试示例:

Iterable<Integer> it = () -> new Iterator<Integer>() {

  private int[] a = new int[]{1, 2, 3};
  private int index = 0;

  @Override
  public boolean hasNext() {
    return index < a.length;
  }

  @Override
  public Integer next() {
    return a[index++];
  }
};
Tmp tmp = new Tmp();
tmp.setO(it);
StandardEvaluationContext context = new StandardEvaluationContext(tmp);

ArrayList<Integer> list = parser.parseExpression("o.?[true]").getValue(context,
    ArrayList.class);