Spring集成在有效负载中传递ImmutableCollection

时间:2016-01-24 14:17:21

标签: java spring-integration

我的场景是从网关触发通道,ImutableList传递给更进一步的SI链。但是从网关触发SI链的步骤失败了。进一步调查错误原因我能够找出失败是因为SI试图转换目标类型的源对象(在我的情况下,源的返回类型和目标方法的参数是相同的)。对于我的情况,它首先使用默认构造函数创建空集合,然后调用addAll方法以插入目标类型中的所有元素。

网关

 <gateway id="fooService"
     service-interface="org.example.FooService"
     default-request-channel="requestChannel"
     default-reply-channel="nullChannel"
     error-channel="errorChannel"/>

<chain input-channel="requestChannel" output-channel="nullChannel">
      <service-activator ref=DummyClass" method="dummyMethod" />
</chain>

转化发生的代码段

public static Collection createCollection(Class<?> collectionType, int initialCapacity) {
if (collectionType.isInterface()) {
    if (List.class.equals(collectionType)) {
        return new ArrayList(initialCapacity);
    }
    else if (SortedSet.class.equals(collectionType) || collectionType.equals(navigableSetClass)) {
        return new TreeSet();
    }
    else if (Set.class.equals(collectionType) || Collection.class.equals(collectionType)) {
        return new LinkedHashSet(initialCapacity);
    }
    else {
        throw new IllegalArgumentException("Unsupported Collection interface: " + collectionType.getName());
    }
}
else {
    if (!Collection.class.isAssignableFrom(collectionType)) {
        throw new IllegalArgumentException("Unsupported Collection type: " + collectionType.getName());
    }
    try {
        // Step where code fails. As immutable implementation will never have a default constructor.
        return (Collection) collectionType.newInstance();
    }
    catch (Exception ex) {
        throw new IllegalArgumentException("Could not instantiate Collection type: " +
                collectionType.getName(), ex);
    }
}}

Source link

我通过使用List暂时修复了它,但我认为应该支持ImmutableCollection。在这种情况下,我如何使用ImmutableCollections。

更新 -20160126

Sample Git Link    我创造了成功和失败案例。

只需要将目标类型更改为任何可变集合,例如List。

1 个答案:

答案 0 :(得分:1)

职业中的Spring Integration POJO方法基于 A C 0 A $12.3K 1 B $12.5K 2 C $0.6K 3 D $7.0K ,允许不关心ConversionService对象,只是尝试将它们强制转换为source类型。

如果是target,我们最终会遇到无法实例化该类的问题,因为它不是接口而且是ImmutableList类。

从一方面来看,最好依靠契约并在方法参数接口中接受,假设任何abstract impl将按原样传递而不进行转换。如果项目属于预期的项目类型,当然,否则Collection会执行这些操作。这就是为什么我们需要接口来允许CollectionToCollectionConverter正确地实例化目标集合。

如果您的服务接受CollectionFactory.createCollection()而不是Message<?>类型,您甚至可以完全绕过转化,例如:

payload

从框架的角度来看,没有任何事情要做,但遗憾的是给您带来了不便。不确定如何帮助其他人,但如果合同将基于接口,则不会收到问题。