Spring Batch如何在后续步骤为FlatFileItemReader动态传入待处理文件名
解决方案
核心使用Spring Batch 内置的步骤作用域(Step Scope) + 延迟绑定特性即可实现,无需重构现有读写逻辑,改动点如下:
1. 改造FlatFileItemReader Bean定义
给Reader添加@StepScope注解,通过@Value动态注入第一步扫描得到的文件路径:
@Bean @StepScope // 声明为步骤作用域,Bean会延迟到步骤执行时才初始化 public FlatFileItemReader<PartnerRelationship> partnerRelationshipReader( // 从作业执行上下文中读取第一步存入的文件路径 @Value("#{jobExecutionContext['targetFilePath']}") String targetFilePath ) throws ParseException { FlatFileItemReader<PartnerRelationship> reader = new FlatFileItemReader<>(); // 动态传入扫描得到的文件路径,不再写死 reader.setResource(new FileSystemResource(targetFilePath)); reader.setBufferedReaderFactory(new CustomFileReaderFactory()); reader.setStrict(false); reader.setLineMapper(new DefaultLineMapper<PartnerRelationship>() {{ setLineTokenizer(new FixedLengthTokenizer() {{ setNames(Constants.partnerRelationshipFields); setColumns(Constants.partnerRelationshipIndeces); }}); setFieldSetMapper(new PartnerRelationshipFieldSetMapper()); }}); return reader; }
2. 第一步监听Tasklet中存入文件路径
在你现有的文件扫描Tasklet逻辑中,找到匹配文件后将路径存入作业执行上下文:
@Component public class FileListenerTasklet implements Tasklet { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { // 替换为你自身的文件扫描逻辑,得到匹配的目标文件 File targetFile = scanMatchFile(); // 将文件路径存入作业执行上下文,供后续步骤的Reader读取 chunkContext.getStepContext() .getStepExecution() .getJobExecution() .getExecutionContext() .put("targetFilePath", targetFile.getAbsolutePath()); return RepeatStatus.FINISHED; } }
实现原理
- 标注了
@StepScope的Bean不会在Spring容器启动阶段初始化,会延迟到对应步骤实际执行时才完成实例化,此时第一步的文件扫描逻辑已经执行完毕,路径已经确定 @Value("#{jobExecutionContext['targetFilePath']}")会从作业执行上下文中读取你存入的文件路径,动态设置为Reader的资源
该方案完全保留了FlatFileItemReader+JdbcBatchItemWriter的高性能处理能力。
内容的提问来源于stack exchange,提问作者Brian Gurka
相关产品推荐
相关产品推荐

