Spring Batch для одновременной обработки нескольких элементов

Мы используем Spring Batch для некоторой обработки, считывая некоторые идентификаторы через Reader, и мы хотим обрабатывать их как «куски» через процессор, а затем записывать в несколько файлов. Но интерфейс процессора позволяет обрабатывать только один элемент за раз, нам нужно выполнять массовую обработку, потому что процессор зависит от третьей стороны и вызов службы для каждого элемента не является вариантом.

Я видел, что мы можем создать оболочки для всех устройств чтения-процессора-записи, задействованных в «чанке», чтобы обрабатывать List ‹> и делегировать их какому-то конкретному устройству чтения / процессора / записи. но мне это не кажется приятным. Нравится:

   <batch:chunk reader="wrappedReader" processor="wrappedProcessor" writer="wrappedWriter" 
commit-interval="2"/>

Есть ли опция «разбивки на части», которая позволяет разбивать на части перед процессором? а не до Writer.

Ваше здоровье,


person tonakai    schedule 10.12.2015    source источник


Ответы (2)


Я бы порекомендовал перенастроить ваш ItemReader, чтобы он возвращал «кусок», который необходимо обработать, поскольку это действительно «элемент», который вы обрабатываете.

person Michael Minella    schedule 11.12.2015
comment
да, в конце мы написали несколько оболочек для ItemReader, возвращающего чанки, и для ItemWriter, который может обрабатывать чанки таким же образом. - person tonakai; 14.12.2015

Поскольку изменение всей механики Spring Batch для одновременной обработки нескольких элементов кажется действительно сложным, я предлагаю вам перенести вашу стороннюю обработку на писатель, который на самом деле может обрабатывать кусок элемента сразу.

Поскольку вам, очевидно, потребуется поддерживать текущий писатель, вы можете просто использовать CompositeItemWriter с 2 (или более) делегатами: ваш новый пользовательский ItemWriter и ваш текущий. Порядок определения имеет значение, так как это будет порядок, в котором они будут вызываться.


ОБНОВЛЕНИЕ

Поскольку использование двух разных ItemWriter внутри CompositeItemWriter не позволяет вам сохранять модификации первого во втором, вы также можете использовать ItemWriteListener.

Реализуя метод beforeWrite, вы можете вызвать свою третью сторону с фактическим фрагментом прямо перед его записью:

@Override
public void beforeWrite(List<? extends T> items) {
    //Third party call on item chunk
}
person Thrax    schedule 10.12.2015
comment
вы имеете в виду CompositeItemWriter? поскольку вы не можете добавить ItemWriter в CompositeItemProcessor. возможно, мы сможем создать Custom ItemWriter, который будет выполнять сторонний вызов, как вы упомянули, вместе с делегатом ItemWriter, чтобы мы могли передать результат делегату после стороннего вызова. все еще не лучшее решение, учитывая, что наша «бизнес-логика» должна быть в процессоре. - person tonakai; 10.12.2015
comment
@tonakai Да, я имел в виду писателя. И вы также правы относительно делегата внутри настраиваемого писателя, если вам нужно записать результат третьей стороны. В противном случае композит просто запишет элемент в его состоянии постобработки без предыдущих результатов. - person Thrax; 10.12.2015
comment
@tonakai Я обновил свой ответ другим решением, учитывая, что вам нужно сохранить изменение элемента, вызванное вызовом третьей стороны. - person Thrax; 10.12.2015
comment
Что касается обновления, да, это похоже на другое решение, но на этот раз нам нужно изменить тип возвращаемого значения моего Reader, чтобы он соответствовал типу возврата стороннего вызова, тогда я могу изменить содержимое списка без особых проблем. - person tonakai; 10.12.2015