Spring Batch MultiResourcePartitioner如何按文件名设置资源处理顺序
问题根因
- 原生
MultiResourcePartitioner的partition方法内部使用HashMap存储分区元数据,HashMap不保证插入顺序,即使传入的Resource数组是有序的,最终生成的分区列表也会打乱顺序。 - 你的现有代码存在调用顺序错误:先执行
partitioner.partition(1)再调用setResources,相当于先基于空资源生成了分区,后续设置的资源列表完全没有生效,进一步导致处理顺序异常。
修复方案
方案1:自定义有序分区器(推荐)
直接继承MultiResourcePartitioner,重写partition方法,使用LinkedHashMap存储分区,完全保留资源数组的插入顺序:
public class OrderedMultiResourcePartitioner extends MultiResourcePartitioner { @Override public Map<String, ExecutionContext> partition(int gridSize) { Resource[] resources = getResources(); // 使用LinkedHashMap保留插入顺序 Map<String, ExecutionContext> partitions = new LinkedHashMap<>(); for (int i = 0; i < resources.length; i++) { ExecutionContext context = new ExecutionContext(); context.put("fileName", resources[i].getFilename()); context.put("file", resources[i]); partitions.put("partition-" + i, context); } return partitions; } }
修改你的Bean定义,替换为自定义分区器,同时修正逻辑和调用顺序:
@Bean @JobScope public OrderedMultiResourcePartitioner paritioner() throws IOException { OrderedMultiResourcePartitioner partitioner = new OrderedMultiResourcePartitioner(); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); // 按你需要的逆序排序文件,直接生成有序的Resource数组即可,不需要HashMap中转 Resource[] resources = listFiles.stream() .sorted(Comparator.reverseOrder()) .map(path -> resolver.getResource("file:" + path)) .toArray(Resource[]::new); // 不需要手动调用partition方法,Spring Batch执行时会自动调用 partitioner.setResources(resources); return partitioner; }
方案2:配置分区比较器
如果不想自定义分区器,可以在配置分区Step时,给PartitionHandler设置自定义分区排序器,按照分区名的后缀数字排序即可保证顺序和传入的资源数组一致:
@Bean public TaskExecutorPartitionHandler partitionHandler(TaskExecutor taskExecutor, Step slaveStep) { TaskExecutorPartitionHandler handler = new TaskExecutorPartitionHandler(); handler.setTaskExecutor(taskExecutor); handler.setStep(slaveStep); handler.setGridSize(listFiles.size()); // 设置分区比较器,按分区序号升序处理 handler.setPartitionComparator(Comparator.comparingInt(partitionName -> Integer.parseInt(partitionName.split("-")[1]) )); return handler; }
内容的提问来源于stack exchange,提问作者Houssem MAAMRIA
相关产品推荐
相关产品推荐

