1

给定一个 使用面向块的处理的Spring Batch作业,我需要根据属性的值将相同的数据写入不同的文件。换句话说,我需要在运行时根据属性的值来确定输出文件名。

我在SO上找到了这个答案,看起来我可以使用 a 在运行时动态创建编写器。ClassifierCompositeItemWriter

我想了解的是,是否会为每次写入ClassifierCompositeItemWriter创建一个新实例?ItemWriter如果不是,如何ClassifierCompositeItemWriter知道域对象中的哪个属性值用于缓存ItemWriter实例以便可以重用它们?(而不是为每个对象创建一个新ItemWriter的..)

我需要自己实现 wrtiers 的缓存还是由ClassfierCompositeItemWriter自动处理?

假设 writer 的 cahcing 需要手动实现,我想出了以下实现。但是,我会假设这是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);

}
4

0 回答 0