【问题标题】:Spring SpEL chooses wrong method to invokeSpring SpEL 选择了错误的方法来调用
【发布时间】:2015-05-09 13:43:21
【问题描述】:

我正在尝试评估以下 SpEL 表达式(Spring 表达式版本 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 个方法与调用匹配(如果其中一个方法是可变参数),则将调用后面的方法(按顺序),而不是选择不是可变参数的方法(更具体)。 JDK似乎不保证方法的排序顺序:不同的运行显示不同的顺序。

有没有办法解决这个问题?

【问题讨论】:

  • 向 Spring 的开发人员发送实现正确行为的补丁?
  • 作为一种解决方法,我建议您引入自己的 util 类,并委托该 Guava 方法。同时,您可以就此事打开 JIRA 问题:jira.spring.io/browse/SPR

标签: spring openjdk spring-el


【解决方案1】:

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

"#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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 2021-05-26
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 2013-07-29
    相关资源
    最近更新 更多