




本文介绍如何在 spring batch 中高效处理同一目录下多个 json 文件(如按国家/地区和类型排序),通过“每文件一作业实例”策略实现真正并行读取与写入,兼顾顺序控制、可扩展性与容错能力。
在 Spring Batch 中,一个 Step 内确实不支持多个 Reader 实例同时运行——这是框架设计的基本约束:每个 Step 绑定唯一 ItemReader,其生命周期与 Step 强耦合。因此,试图在单 Step 内动态切换或并发启动多个 Reader(如为每个 JSON 文件分配独立 Reader)不仅违背模型语义,还会引发状态冲突、事务边界混乱及难以调试的竞态问题。
正确的解法是转变粒度:从“单作业多文件”升级为“多作业实例,每实例处理单文件”。这并非绕过限制,而是遵循 Spring Batch 的核心哲学——以作业(Job)为最小可调度、可追踪、可恢复的执行单元。
将每个待处理文件路径作为唯一标识性 Job Parameter(如 inputFil

// 启动作业示例(如在 Controller 或 Scheduler 中)
JobParameters params = new JobParametersBuilder()
.addString("inputFile", "/data/company_group/sg_company_group_alternate_id.json")
.addLong("timestamp", System.currentTimeMillis())
.toJobParameters();
jobLauncher.run(fileProcessingJob, params);对应地,定义一个泛化 Job:
其中 jsonFileItemReader 是参数化 Reader:
@Bean @StepScope public JsonItemReaderjsonFileItemReader( @Value("#{jobParameters['inputFile']}") String inputFile) { JsonItemReader reader = new JsonItemReader<>(); reader.setResource(new FileSystemResource(inputFile)); reader.setJsonObjectReader(new JacksonJsonObjectReader<>(CompanyGroup.class)); reader.setLinesToSkip(1); // 如需跳过 header return reader; }
虽然作业实例彼此独立,但你仍可通过外部逻辑保障执行顺序:
综上,放弃“单 Step 多 Reader”的设想,拥抱“每文件一作业”的范式,不仅能自然解决并发读取问题,更带来弹性伸缩、精准重试、清晰追踪等企业级优势——这才是 Spring Batch 在真实场景中的正确打开方式。