Spring batch Spring批处理:java配置文件中的并行步骤执行
我试图在java配置文件中创建一个关于并行步骤执行的示例应用程序,但对于有多少文件(作业存储库、作业启动程序和执行等)正在配置和初始化以及如何配置感到困惑?Spring batch Spring批处理:java配置文件中的并行步骤执行,spring-batch,Spring Batch,我试图在java配置文件中创建一个关于并行步骤执行的示例应用程序,但对于有多少文件(作业存储库、作业启动程序和执行等)正在配置和初始化以及如何配置感到困惑? 简单地说,我需要一个示例应用程序来阐明作业中步骤并行执行的基本原理。这里是不同数据集上的基本并行步骤执行,基本上您必须提供一个分区器,它将为每个步骤创建seprate上下文,并基于上下文,您可以处理其数据集 <batch:job id="myJob" job-repository="jobRepository">
简单地说,我需要一个示例应用程序来阐明作业中步骤并行执行的基本原理。这里是不同数据集上的基本并行步骤执行,基本上您必须提供一个分区器,它将为每个步骤创建seprate上下文,并基于上下文,您可以处理其数据集
<batch:job id="myJob" job-repository="jobRepository">
<batch:step id="master">
<batch:partition step="step1" partitioner="stepPartitioner ">
<batch:handler grid-size="4" task-executor="taskExecutor"/>
</batch:partition>
</batch:step>
</batch:job>
<batch:step id="step1">
<batch:tasklet>
<batch:chunk reader="myReader" processor="myProcessor" writer="myWriter"
commit-interval="10"/>
</batch:tasklet>
</batch:step>
public class stepPartitioner implements Partitioner {
@Autowired
DaoInterface daoInterface;
@Override
public Map<String, ExecutionContext> partition(int i) {
Map<String, ExecutionContext> result = new HashMap<>();
List<String> keys= daoInterface.getUniqueKeyForStep();
for(String key: keys){
ExecutionContext executionContext = new ExecutionContext();
executionContext.putString("key", key);
result.put(key,executionContext);
}
return result;
}
}
公共类stepPartitioner实现了分区器{
@自动连线
dao接口dao接口;
@凌驾
公共地图分区(int i){
映射结果=新的HashMap();
List keys=daoInterface.getUniqueKeyForStep();
用于(字符串键:键){
ExecutionContext ExecutionContext=新的ExecutionContext();
putString(“key”,key);
result.put(key,executionContext);
}
返回结果;
}
}
下面是一个通过java配置使用拆分的示例。在此示例中,流1和2将并行执行:
@Configuration
public class BatchConfiguration {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Tasklet tasklet() {
return new CountingTasklet();
}
@Bean
public Flow flow1() {
return new FlowBuilder<Flow>("flow1")
.start(stepBuilderFactory.get("step1")
.tasklet(tasklet()).build())
.build();
}
@Bean
public Flow flow2() {
return new FlowBuilder<Flow>("flow2")
.start(stepBuilderFactory.get("step2")
.tasklet(tasklet()).build())
.next(stepBuilderFactory.get("step3")
.tasklet(tasklet()).build())
.build();
}
@Bean
public Job job() {
return jobBuilderFactory.get("job")
.start(flow1())
.split(new SimpleAsyncTaskExecutor()).add(flow2())
.end()
.build();
}
public static class CountingTasklet implements Tasklet {
@Override
public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
System.out.println(String.format("%s has been executed on thread %s", chunkContext.getStepContext().getStepName(), Thread.currentThread().getName()));
return RepeatStatus.FINISHED;
}
}
}
@配置
公共类批处理配置{
@自动连线
私人JobBuilderFactory JobBuilderFactory;
@自动连线
私人StepBuilderFactory StepBuilderFactory;
@豆子
公共Tasklet Tasklet(){
返回新的CountingTasklet();
}
@豆子
公共流量1(){
返回新的FlowBuilder(“flow1”)
.start(stepBuilderFactory.get(“step1”)
.tasklet(tasklet()).build())
.build();
}
@豆子
公共流量2(){
返回新的FlowBuilder(“flow2”)
.start(stepBuilderFactory.get(“step2”)
.tasklet(tasklet()).build())
.next(stepBuilderFactory.get(“step3”)
.tasklet(tasklet()).build())
.build();
}
@豆子
公职{
返回jobBuilderFactory.get(“作业”)
.start(flow1())
.split(新的SimpleAsyncTaskExecutor()).add(flow2())
(完)
.build();
}
公共静态类CountingTasklet实现Tasklet{
@凌驾
public RepeatStatus execute(StepContribution StepContribution,ChunkContext ChunkContext)引发异常{
System.out.println(String.format(“%s”已在线程%s上执行),chunkContext.getStepContext().getStepName(),thread.currentThread().getName());
返回RepeatStatus.FINISHED;
}
}
}
假设您有步骤A、B1、B2、B3、C。您希望并行运行B1、B2和B3。首先需要为它们创建子流,然后使用SimpleAsynctAskeExecutor()将其添加到一个流中:
@Bean
公职
{
最终流flowB1=新的FlowBuilder(“子流B1”)。从(stepb1()).end();
最终流flowB2=新的FlowBuilder(“子流B2”)。从(步骤B2()).end();
最终流flowB3=新的FlowBuilder(“子流B3”)。来自(步骤B3())。结束();
最终流量拆分流量=新流量生成器(“拆分流量”)
.启动(流程B1)
.split(新的SimpleAsyncTaskExecutor())
.add(flowB2,flowB3).build();
返回jobBuilderFactory
.flow(stepA())
.下一步(分流)
.next(stepC())
(完)
.build();
}
这不是javaconfig示例Yeah@sandeep这不是javaconfig示例。。我需要javaconfig.Yes中的所有内容。因为我只想知道多个步骤如何并行运行。因此,这给了我一个想法。@MichaelMinella我有一个场景,其中流的数量取决于表中的行数。因此,每个流都应该以每一行作为输入来运行。有没有办法做到这一点?这就是答案!如果需要,也不需要设置tasklet。在每个步骤中,它都可以在没有tasklet的情况下工作also@NitishKumar您的评论是对我的吗?@Ganapathi004 noth语法有点混乱:在开始时调用flowB1,然后调用split,然后添加确保所有3个都并行运行,还是只运行B2和B3?
@Bean
public Job job()
{
final Flow flowB1 = new FlowBuilder<Flow>("subflowb1").from(stepb1()).end();
final Flow flowB2 = new FlowBuilder<Flow>("subflowb2").from(stepb2()).end();
final Flow flowB3 = new FlowBuilder<Flow>("subflowb3").from(stepb3()).end();
final Flow splitFlow = new FlowBuilder<Flow>("splitFlow")
.start(flowB1)
.split(new SimpleAsyncTaskExecutor())
.add(flowB2, flowB3).build();
return jobBuilderFactory
.flow(stepA())
.next(splitFlow)
.next(stepC())
.end()
.build();
}