Spring Batch: как ClassifierCompositeItemWriter решает, создавать ли новый писатель или использовать существующий?
Учитывая задание Spring Batch, в котором используется обработка, ориентированная на фрагменты, у меня есть требование записывать одни и те же данные в разные файлы в зависимости от значения атрибута. Другими словами, мне нужно, чтобы имя выходного файла определялось во время выполнения в зависимости от значения атрибута.
Я нашел этот ответ на SO, и похоже, что могу использоватьClassifierCompositeItemWriter
для динамического создания писателей во время выполнения.
Я хочу понять, что ClassifierCompositeItemWriter
создаст новый ItemWriter
экземпляр для каждой записи? Если нет, то какClassifierCompositeItemWriter
знать, какое значение атрибута из объекта домена использовать для кэширования ItemWriter
экземпляры, чтобы их можно было использовать повторно? (вместо того, чтобы создавать новыйItemWriter
за объект..)
Нужно ли мне самому реализовывать кеширование писем или этим занимается ClassfierCompositeItemWriter
автоматически?
Предполагая, что кеширование писателей необходимо реализовать вручную, я придумал следующую реализацию. Однако я бы предположил, что это что-тоClassfierCompositeItemWriter
будет делать сам?
public abstract class AbstractFileWriterClassifier<T> implements Classifier<T, ItemWriter<T>> {
private static final long serialVersionUID = 906600779221731593L;
private transient LineAggregator<T> lineAggregator;
private transient FlatFileHeaderCallback headerCallback;
private transient String baseFilePath;
private transient boolean appendAllowed;
private transient Map<String, ItemWriter<T>> cachedItemWriters;
public AbstractFileWriterClassifier() {
cachedItemWriters = new ConcurrentHashMap<>(5);
}
@Override
public final ItemWriter<T> classify(T item) {
final String dynamicFilePath = getDynamicFilePath(item);
// Get existing writer or create a new one if it doesn't exist for the key
return cachedItemWriters.computeIfAbsent(dynamicFilePath, dynamicPath -> {
String fileName = baseFilePath + dynamicPath;
FlatFileItemWriter<T> itemWriter = new FlatFileItemWriter<>();
itemWriter.setResource(new FileSystemResource(fileName));
itemWriter.setAppendAllowed(appendAllowed);
itemWriter.setLineAggregator(lineAggregator);
itemWriter.setHeaderCallback(headerCallback);
itemWriter.open(new ExecutionContext());
return itemWriter;
});
}
/**
* Derives the dynamic part of the file path using the item
*
* @param item
* @return
*/
protected abstract String getDynamicFilePath(T item);
}