如您所知,spring-batch 中的处理器可以与复合处理器链接。在链中,您可以在处理器之间更改处理类型,但当然两个“邻居”处理器的输入和输出类型必须匹配。
但是,输入输出输出类型始终被视为一项。因此,如果处理器的输出类型是列表,则该列表被视为一项。因此,下面的处理器需要有一个 InputType“List”,如果一个 writer 跟随,那么 Writer 需要一个 List-of-List 作为其 write-method 的类型。
此外,处理器不能乘以它的元素。每个输入元素只能有一个输出项。
基本上,拥有这样的链条并没有错
Reader<Integer>
ProcessorA<Integer,List<Integer>>
ProcessorB<List<Integer>,List<Integer>>
Writer<List<Integer>> (which leads to a write-method write(List<List<Integer>> items)
根据具体情况,可能会有更好的解决方案。
您可以通过使用 wrapper-processors 和 wrapper-writer 来减轻影响(例如可重用性),例如以下代码示例:
public class ListWrapperProcessor<I,O> implements ItemProcessor<List<I>, List<O>> {
ItemProcessor<I,O> delegate;
public void setDelegate(ItemProcessor<I,O> delegate) {
this.delegate = delegate;
}
public List<O> process(List<I> itemList) {
List<O> outputList = new ArrayList<>();
for (I item : itemList){
O outputItem = delegate.process(item);
if (outputItem!=null) {
outputList.add(outputItem);
}
}
if (outputList.isEmpty()) {
return null;
}
return outputList;
}
}
public class ListOfListItemWriter<T> implements InitializingBean, ItemStreamWriter<List<T>> {
private ItemStreamWriter<T> itemWriter;
@Override
public void write(List<? extends List<T>> listOfLists) throws Exception {
if (listOfLists.isEmpty()) {
return;
}
List<T> all = listOfLists.stream().flatMap(Collection::stream).collect(Collectors.toList());
itemWriter.write(all);
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(itemWriter, "The 'itemWriter' may not be null");
}
public void setItemWriter(ItemStreamWriter<T> itemWriter) {
this.itemWriter = itemWriter;
}
@Override
public void close() {
this.itemWriter.close();
}
@Override
public void open(ExecutionContext executionContext) {
this.itemWriter.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) {
this.itemWriter.update(executionContext);
}
}
使用此类包装器,您仍然可以实现“普通”处理器和编写器,然后使用此类包装器将“列表”处理移出它们。