在Spring-Batch作业中,我有两个业务操作,A和B,每个都有几个步骤(1,2,3)。 我希望并行运行A1和B1,当两者都结束时,我想以并行方式运行A2和B2:
start
A1-B1 in parallel
wait for both ended
A2-B2 in parrallel
wait for both ended
A3-B3 in parrallel
...
我试了一下:
@Bean
public Job test() {
SimpleFlow splitFlow = new FlowBuilder<SimpleFlow>("Sequential Flow")
.split(new SyncTaskExecutor())
.add(flow1(), flow2())
.build();
return jobs.get("test").start(splitFlow).end().build();
}
private Flow flow1() {
return new FlowBuilder<SimpleFlow>("parralel 1").split(new SimpleAsyncTaskExecutor())
.add(new FlowBuilder<SimpleFlow>("A1").start(stepA1()).build(),
new FlowBuilder<SimpleFlow>("B1").start(stepB1()).build())
.build();
}
private Flow flow2() {
return new FlowBuilder<SimpleFlow>("parralel 2").split(new SimpleAsyncTaskExecutor())
.add(new FlowBuilder<SimpleFlow>("A2").start(stepA2()).build(),
new FlowBuilder<SimpleFlow>("B2").start(stepB2()).build())
.build();
}
它正在发挥作用。
但它也很难看,几乎不可读。有没有更容易做到的?
(我可以从一个工作岗位转到另一个工作岗位,再到工作岗位并让他们互相等待,但该怎么做?)
修改: 我在xml config中找到了等价物:
<batch:job id="test">
<batch:split id="step_1" next="step_2">
<batch:flow>
<batch:step id="A1"/>
</batch:flow>
<batch:flow>
<batch:step id="B1" />
</batch:flow>
</batch:split>
<batch:split id="step_2">
<batch:flow>
<batch:step id="A2"/>
</batch:flow>
<batch:flow>
<batch:step id="B2" />
</batch:flow>
</batch:split>
</batch:job>
我的所有配置目前都在Java配置中,但是对于这些作业,xml配置更易于阅读和理解。
答案 0 :(得分:0)
如果只是可读性,有两种选择:
a)以不同方式格式化代码
private Flow flow1() {
return new FlowBuilder<SimpleFlow>("parralel 1")
.split(new SimpleAsyncTaskExecutor())
.add(
new FlowBuilder<SimpleFlow>("A1").start(stepA1()).build(),
new FlowBuilder<SimpleFlow>("B1").start(stepB1()).build()
).build();
}
private Flow flow2() {
return new FlowBuilder<SimpleFlow>("parralel 2")
.split(new SimpleAsyncTaskExecutor())
.add(
new FlowBuilder<SimpleFlow>("A2").start(stepA2()).build(),
new FlowBuilder<SimpleFlow>("B2").start(stepB2()).build())
.build();
}
b)提取方法和变量
private TaskExecutor executor() {
return new SimpleAsyncTaskExecutor();
}
private Flow flow1() {
Flow subFlow1 = new FlowBuilder<SimpleFlow>("A1").start(stepA1()).build();
Flow subFlow2 = new FlowBuilder<SimpleFlow>("B1").start(stepB1()).build();
return new FlowBuilder<SimpleFlow>("parralel 1")
.split(executor())
.add(subFlow1, subFlow2)
.build();
}
private Flow flow2() {
Flow subFlow1 = new FlowBuilder<SimpleFlow>("A2").start(stepA2()).build();
Flow subFlow2 = new FlowBuilder<SimpleFlow>("B2").start(stepB2()).build();
return new FlowBuilder<SimpleFlow>("parralel 2")
.split(executor())
.add(subFlow1, subFlow2)
.build();
}
顺便说一句,我很确定你应该在两个流程中使用相同的TaskExecutor
。您可以通过将executor()方法设为public并将其标记为@Bean
来实现此目的。然后Spring将确保只创建一次底层对象(参见The IOC Container)。所以上面的executor()方法实际上应该是:
@Bean
public TaskExecutor executor() {
return new SimpleAsyncTaskExecutor();
}