Spring批处理在tasklet中执行动态生成的步骤

Spring批处理在tasklet中执行动态生成的步骤,spring,spring-batch,Spring,Spring Batch,我有一个spring批处理作业,它执行以下操作 第一步。创建需要处理的对象列表 第二步。根据在步骤1中创建的对象列表中有多少项,创建步骤列表 第三步。尝试执行步骤2中创建的步骤列表中的步骤 下面在executeDynamicStepsTasklet()中执行x个步骤。虽然代码运行时没有任何错误,但它似乎没有做任何事情。我的方法看起来正确吗 谢谢 /* * */ @配置 公共类ExportMasterListCsvJobConfig{ 公共静态最终字符串作业\u NAME=“exportMaste

我有一个spring批处理作业,它执行以下操作

第一步。创建需要处理的对象列表

第二步。根据在步骤1中创建的对象列表中有多少项,创建步骤列表

第三步。尝试执行步骤2中创建的步骤列表中的步骤

下面在executeDynamicStepsTasklet()中执行x个步骤。虽然代码运行时没有任何错误,但它似乎没有做任何事情。我的方法看起来正确吗

谢谢

/* * */

@配置
公共类ExportMasterListCsvJobConfig{
公共静态最终字符串作业\u NAME=“exportMasterListCsv”;
@自动连线
公共建筑商建筑商工厂;
@自动连线
公共StepBuilderFactory StepBuilderFactory;
@值(${exportMasterListCsv.generateMasterListRows.chunkSize}”)
公共规模;
@值(${exportMasterListCsv.generateMasterListRows.masterListSql}”)
公共字符串masterListSql;
@自动连线
公共数据源在线StagingDB;
@值(“${out.dir}”)
公共字符串outDir;
@值(${exportMasterListCsv.GeneratePromotStartDateEndDateGroupings.PromotStartDateEndDateSQL}”)
私有字符串promotStartDateEndDateSQL;
私有列表分区PROMOCOMPSTARTNDDTGROUPING;
私有列表dynamicSteps=Collections.synchronizedList(新的ArrayList());
@豆子
公共作业exportMasterListCsvJob(
@限定符(“createJobDatesStep”)步骤createJobDatesStep,
@限定符(“createDynamicStepsStep”)步骤createDynamicStepsStep,
@限定符(“ExecutedDynamicStepsStep”)步骤ExecutedDynamicStepsStep){
返回jobBuilderFactory.get(作业名称)
.flow(createJobDatesStep)
.下一步(createDynamicStepsStep)
.下一步(执行步骤步骤)
.end().build();
}   
@豆子
执行的公共步骤动态步骤步骤步骤(
@限定符(“executeDynamicStepsTasklet”)Tasklet executeDynamicStepsTasklet){
返回stepBuilderFactory
.get(“已执行的动态步骤”)
.tasklet(已执行)
.build();
}
@豆子
public Tasklet executedDynamicStepstasklet(){
返回新的Tasklet(){
@凌驾
public RepeatStatus execute(StepContribution贡献,ChunkContext ChunkContext)引发异常{
FlowStep FlowStep=新的FlowStep(createParallelFlow());
SimpleJobBuilder jobBuilder=jobBuilderFactory.get(“myNewJob”).start(flowStep);
返回RepeatStatus.FINISHED;
}
};
}
公共流createParallelFlow(){
SimpleAsyncTaskExecutor taskExecutor=新的SimpleAsyncTaskExecutor();
taskExecutor.setConcurrencyLimit(1);
列表流=dynamicSteps.stream()
.map(步骤->新建FlowBuilder(“流”+步骤.getName()).start(步骤.build())
.collect(Collectors.toList());
返回新的FlowBuilder(“parallelStepsFlow”)
.split(任务执行器)
.add(flows.toArray(新流[flows.size()]))
.build();
}
@豆子
公共步骤createDynamicStepsStep(
@限定符(“createDynamicStepsTasklet”)Tasklet createDynamicStepsTasklet){
返回stepBuilderFactory
.get(“createDynamicStepsStep”)
.tasklet(createDynamicStepsTasklet)
.build();
}   
@豆子
@工作范围
public Tasklet createDynamicStepsTasklet(){
返回新的Tasklet(){
@凌驾
public RepeatStatus execute(StepContribution贡献,ChunkContext ChunkContext)引发异常{
对于(DivisionIDPROMOCOMPStartDendtGrouping grp:DivisionIDPROMOCOMPStartDendtGrouping){
系统错误println(“grp:+grp”);
String stepName=“stp_”+grp;
字符串文件名=grp+FlatFileConstants.EXTENSION\u CSV;
步骤dynamicStep=
stepBuilderFactory.get(stepName)
.chunk(10)
.reader(querystagindbreader(
grp.getDivisionId(),
grp.getrpmpromocompDetailsStartDate(),
grp.getRpmPromoCompDetailEndDate())
.writer(主列表文件编写器(文件名))
.build();
dynamicStep.add(dynamicStep);
} 
System.err.println(“createDynamicStepsTasklet dynamicSteps:+dynamicSteps”);
返回RepeatStatus.FINISHED;
}
};
}
公共FlatFileItemWriter masterListFileWriter(字符串文件名){
FlatFileItemWriter writer=新的FlatFileItemWriter();
writer.setResource(新文件系统资源(新文件(outDir,fileName));
writer.setHeaderCallback(masterListFlatFileHeaderCallback());
writer.setLineAggregator(masterListFormatterLineAggregator());
返回作者;
}

因此,现在我有一个需要执行的动态步骤列表,我相信它们在StepScope中。有人能告诉我如何执行它们吗?

这将不起作用。您的Tasklet只是创建一个以FlowStep作为第一步的作业。使用jobBuilderfactory只创建作业。它不会启动它。方法名为“start”这可能会产生误导,因为这只定义了第一步。但它不会启动作业

一旦作业启动,您就无法更改其结构(其步骤和子步骤)。因此,无法根据步骤1中计算的内容在步骤2中配置flowstep。(当然,您可以在springbatch结构内部进行更深入的黑客攻击,并直接修改bean等等……但您不想这样做)

我建议您使用一种“SetupBean”和适当的postConstruct方法,该方法被注入到配置作业的类中。该“SetupBean”负责计算正在处理的对象列表

@Component
public class SetUpBean {

  private List<Object> myObjects;

  @PostConstruct
  public afterPropertiesSet() {
    myObjects = ...;
  }

  public List<Object> getMyObjects() {
   return myObjects;
  }
}

@Configuration
public class JobConfiguration {

   @Autowired
   private JobBuilderFactory jobBuilderFactory;

   @Autowired
   private StepBuilderFactory stepBuilderFactory;

   @Autowired
   private SetUpBean setup;

   ... 
}
@Co
@Component
public class SetUpBean {

  private List<Object> myObjects;

  @PostConstruct
  public afterPropertiesSet() {
    myObjects = ...;
  }

  public List<Object> getMyObjects() {
   return myObjects;
  }
}

@Configuration
public class JobConfiguration {

   @Autowired
   private JobBuilderFactory jobBuilderFactory;

   @Autowired
   private StepBuilderFactory stepBuilderFactory;

   @Autowired
   private SetUpBean setup;

   ... 
}