我认为这应该是一个很常规的用例,但是我对spring-batch还是很陌生,并被一些概念所迷惑。
我希望有一个从目录中读取文件的批处理过程(将它们作为File
对象获取)。还应该对其进行分区和可重启。
搜索主要生成FlatFileItemReader
的示例,我认为不是我所需要的(我不想读取它们,只需将它们作为File发送给处理器)即可。
此刻,我的分区器和读取器看起来像这样。
@Bean("partitioner")
@StepScope
public Partitioner partitioner() {
MultiResourcePartitioner partitioner = new MultiResourcePartitioner();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = null;
try {
resources = resolver.getResources("classpath*:/*.json");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
partitioner.setResources(resources);
partitioner.partition(10);
return partitioner;
}
@Bean
@StepScope
@Qualifier("fileItemReader")
@DependsOn("partitioner")
public ItemReader<File> fileItemReader(@Value("#{stepExecutionContext['fileName']}") String fileName){
log.info("fileName from stepExecutionContext is " + fileName);
return new ItemReader<File>() {
//Reader has to return null, when he ended
boolean fileHasBeenRead = false;
@Override
public File read() throws CustomRetryableException, FileNotFoundException {
if (fileHasBeenRead == true){
log.info("has been read already");
return null;
}
else {
fileHasBeenRead = true;
return ResourceUtils.getFile(fileName);
}
}
};
}
我觉得这个阅读器实现不是很好,而且似乎也无法重启。
我找到了另一个阅读器示例,但不知道它是否适用于分区FileReader Example。
我也偶然发现了MultiResourceItemReader
,但不确定是否也可以解决。
使用分区和ItemReader来处理File对象同时又具有可重启性的最佳方法是什么?
答案 0 :(得分:0)
Spring Batch不提供任何返回ItemReader
对象的File
实现,因此您正确地需要自己实现。到此为止,让我们看一下Spring Batch如何使其组件可重启。
启用重新启动功能的主要界面是ItemStream
界面。该界面有以下三种方法:
public interface ItemStream {
void open(ExecutionContext executionContext) throws ItemStreamException;
void update(ExecutionContext executionContext) throws ItemStreamException;
void close() throws ItemStreamException;
}
open
方法用于建立组件的状态并初始化需要该组件的任何组件(打开文件/等)。这也是在重新启动作业时恢复组件状态的位置。从ExecutionContext
检索状态,无非就是先前执行中保存的键/值对映射。
通过update
方法可以使组件有机会定期保存其当前状态。诸如读取的记录数之类的内容将存储在ExecutionContext
中,稍后将其保存到作业存储库中,以供以后在重新启动时进行引用(通过上面讨论的open
方法)。
最后,close
方法用于释放任何不需要的资源并执行任何最终清理(关闭文件和数据库连接等)。
当我们考虑先前的方法时,可重启组件将实现ItemStream
接口,以便update
方法将保存重启到ExecutionContext
和打开方法将查找该状态,如果存在,则将其还原(如果没有以前的状态,则不是重启)。
考虑到所有这些,我们现在可以看看您创建ItemReader
实现的特定用例,该实现允许返回File
对象并且可以重新启动。在这种情况下,您实际上有两件事要确定:
AbstractItemCountingItemStreamItemReader
。父类将自动计算已返回的项目数,并将它们存储在ExecutionContext
中。这意味着,当您遍历Resource
对象的数组时,AbstractItemCountingItemStreamItemReader
将跟踪您所在的索引。因此,在您的open
方法中,您可以获取资源数组并对其进行排序。从那里开始,您将拥有一个一致的数据集,您所需要的就是索引,以识别已阅读的项目和未阅读的项目。祝你好运,希望对你有帮助!