此文主要参考《spring batch in action》的第10章controlling execution。在之前介绍了batch按step线性执行任务,实际上它也可以执行一定复杂的流程处理。设计一个简单流程,流程如下
根据以上需求,我们只需要如此配置job
<batch:job id="etljob"> <batch:step id="prepareEtl" next="readWriteStep"> <batch:flow parent="beginEtlFlow" /> </batch:step> <batch:step id="readWriteStep"> <batch:tasklet> <batch:chunk reader="reader" writer="writer" commit-interval="1000" /> </batch:tasklet> </batch:step> </batch:job> <!-- 开始etl,判断表是否存在,不存在就创建表 --> <batch:flow id="beginEtlFlow"> <batch:decision id="tableExistsDecision" decider="tableExistsDecider"> <batch:end on="YES" /> <batch:next on="NO" to="createTbStep" /> </batch:decision> <batch:step id="createTbStep"> <batch:tasklet ref="createTblsTasklet" /> </batch:step> </batch:flow>
在sts的视图里就是下图所示
判断表是否存在的decider
import java.util.Random; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.job.flow.FlowExecutionStatus; import org.springframework.batch.core.job.flow.JobExecutionDecider; import org.springframework.stereotype.Component; @Component("tableExistsDecider") public class TableExistsDecider implements JobExecutionDecider { @Override public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) { if(isTblExist()) return new FlowExecutionStatus("YES"); else return new FlowExecutionStatus("NO"); } //判断表是否存在 private boolean isTblExist(){ Random rd=new Random(); return rd.nextBoolean(); } }
创建表的tasklet
import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.step.tasklet.Tasklet; import org.springframework.batch.repeat.RepeatStatus; import org.springframework.stereotype.Component; @Component("createTblsTasklet") public class CreateTblsTasklet implements Tasklet{ @Override public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { createTable(); return RepeatStatus.FINISHED; } private void createTable(){ System.out.println("finish create table"); } }
reader
import org.springframework.batch.item.ItemReader; import org.springframework.stereotype.Component; @Component("reader") public class Reader implements ItemReader<String> { private String[] input = {"Hello world!", null}; private int index = 0; /** * Reads next record from input */ public String read() throws Exception { System.out.println("first Reader"); if (index < input.length) { return input[index++]; } else { return null; } } }
writer
@Component("writer") public class Writer implements ItemWriter<Object> { private static final Log log = LogFactory.getLog(Writer.class); public void write(List<? extends Object> data) throws Exception { log.info(data); System.out.println("first Writer"); } }