下载 2 个文件 Spring 批处理步骤
Download 2 files Spring Batch Step
我正在构建一个 Spring 批处理作业,它包含 2 个步骤来下载 2 个文件。文件名是作业参数。
请在下面找到步骤配置 class(FileDownloader 和 FileDownloadTasklet 是自定义 classes 用于下载逻辑):
@Autowired
private FileDownloader fileDownloader;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Step downloadFirstFileStep() {
return stepBuilderFactory.get("downloadFirstFileStep")
.tasklet(firstFileDownloadTasklet(null)).build();
}
@Bean
@StepScope
public FileDownloadTasklet firstFileDownloadTasklet(
@Value("#{jobParameters['firstFile']}") String fileName) {
return new FileDownloadTasklet(fileDownloader, fileName);
}
@Bean
public Step downloadSecondFileStep() {
return stepBuilderFactory.get("downloadSecondFileStep")
.tasklet(secondFileDownloadTasklet(null)).build();
}
@Bean
@StepScope
public FileDownloadTasklet secondFileDownloadTasklet(
@Value("#{jobParameters['secondFile']}") String fileName) {
return new FileDownloadTasklet(fileDownloader, fileName);
}
我觉得复制 Step bean 没有做正确的事情,因为唯一的区别是要下载的文件的实际名称。
你能告诉我如何在不复制豆子的情况下做到这一点吗?
是的,我们可以使用分区程序以更好的方式做到这一点。当前您正在下载 2 个文件,将来您可能想要下载更多文件。
@Bean(name = "partitionerJob")
public Job partitionerJob() {
return jobs.get("partitioningJob")
.start(partitionStep())
.build();
}
@Bean
@StepScope
public Step partitionStep() {
return steps.get("partitionStep")
.partitioner("slaveStep", partitioner())
.step(downloadFirstFileStep())
.taskExecutor(taskExecutor())
.build();
}
@Bean
public Step downloadFirstFileStep() {
return stepBuilderFactory.get("downloadFirstFileStep")
.tasklet(firstFileDownloadTasklet(null)).build();
}
@Bean
@StepScope
public FileDownloadTasklet firstFileDownloadTasklet(
@Value("#{stepExecutionContext['fileName']}") String fileName) {
return new FileDownloadTasklet(fileDownloader, fileName);
}
@Bean
public YourPartitioner partitioner() {
return new YourPartitioner();
}
public class YourPartitioner implements Partitioner {
@Value("#{jobParameters['fileNames']}") //Pass Comma separated file names as argument
protected String fileNames;
@Override
public Map<String, ExecutionContext> partition(int gridSize) {
Map<String, ExecutionContext> map = new HashMap<>(gridSize);
int i = 0, k = 1;
for (String resource : fileNames.split(",") {
ExecutionContext context = new ExecutionContext();
context.putString("fileName", resource); //This will be fetched as argument to the step job from JobExecutionContext
map.put("PARTITION_KEY " + i, context);
i++;
}
return map;
}
}
我正在构建一个 Spring 批处理作业,它包含 2 个步骤来下载 2 个文件。文件名是作业参数。
请在下面找到步骤配置 class(FileDownloader 和 FileDownloadTasklet 是自定义 classes 用于下载逻辑):
@Autowired
private FileDownloader fileDownloader;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Step downloadFirstFileStep() {
return stepBuilderFactory.get("downloadFirstFileStep")
.tasklet(firstFileDownloadTasklet(null)).build();
}
@Bean
@StepScope
public FileDownloadTasklet firstFileDownloadTasklet(
@Value("#{jobParameters['firstFile']}") String fileName) {
return new FileDownloadTasklet(fileDownloader, fileName);
}
@Bean
public Step downloadSecondFileStep() {
return stepBuilderFactory.get("downloadSecondFileStep")
.tasklet(secondFileDownloadTasklet(null)).build();
}
@Bean
@StepScope
public FileDownloadTasklet secondFileDownloadTasklet(
@Value("#{jobParameters['secondFile']}") String fileName) {
return new FileDownloadTasklet(fileDownloader, fileName);
}
我觉得复制 Step bean 没有做正确的事情,因为唯一的区别是要下载的文件的实际名称。 你能告诉我如何在不复制豆子的情况下做到这一点吗?
是的,我们可以使用分区程序以更好的方式做到这一点。当前您正在下载 2 个文件,将来您可能想要下载更多文件。
@Bean(name = "partitionerJob")
public Job partitionerJob() {
return jobs.get("partitioningJob")
.start(partitionStep())
.build();
}
@Bean
@StepScope
public Step partitionStep() {
return steps.get("partitionStep")
.partitioner("slaveStep", partitioner())
.step(downloadFirstFileStep())
.taskExecutor(taskExecutor())
.build();
}
@Bean
public Step downloadFirstFileStep() {
return stepBuilderFactory.get("downloadFirstFileStep")
.tasklet(firstFileDownloadTasklet(null)).build();
}
@Bean
@StepScope
public FileDownloadTasklet firstFileDownloadTasklet(
@Value("#{stepExecutionContext['fileName']}") String fileName) {
return new FileDownloadTasklet(fileDownloader, fileName);
}
@Bean
public YourPartitioner partitioner() {
return new YourPartitioner();
}
public class YourPartitioner implements Partitioner {
@Value("#{jobParameters['fileNames']}") //Pass Comma separated file names as argument
protected String fileNames;
@Override
public Map<String, ExecutionContext> partition(int gridSize) {
Map<String, ExecutionContext> map = new HashMap<>(gridSize);
int i = 0, k = 1;
for (String resource : fileNames.split(",") {
ExecutionContext context = new ExecutionContext();
context.putString("fileName", resource); //This will be fetched as argument to the step job from JobExecutionContext
map.put("PARTITION_KEY " + i, context);
i++;
}
return map;
}
}