Spring Batch: Conditional Flow in Jobs
In enterprise applications, you may want to execute certain steps in a batch job based on specific conditions. Spring Batch provides a powerful mechanism to implement this using conditional flow.
🚦 What is Conditional Flow in Spring Batch?
Conditional flow allows you to define paths between steps based on their exit status. This is particularly useful when a step’s outcome determines which step should be executed next. Spring Batch provides two main ways to define conditions:
- Exit Status Based Transitions — Based on return status of a step (e.g., COMPLETED, FAILED)
- JobExecutionDecider — Custom logic to dynamically decide next step
📁 Maven Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
🛠️ Step Configuration
Let’s define three tasklet-based steps: startStep
, successStep
, and failureStep
.
@Bean
public Step startStep() {
return stepBuilderFactory.get("startStep")
.tasklet((contribution, chunkContext) -> {
System.out.println("Executing Start Step...");
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step successStep() {
return stepBuilderFactory.get("successStep")
.tasklet((contribution, chunkContext) -> {
System.out.println("Executing Success Step...");
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step failureStep() {
return stepBuilderFactory.get("failureStep")
.tasklet((contribution, chunkContext) -> {
System.out.println("Executing Failure Step...");
return RepeatStatus.FINISHED;
}).build();
}
🧠 Custom JobExecutionDecider
Let’s define a decider that randomly chooses between success and failure path.
@Component
public class RandomDecider implements JobExecutionDecider {
@Override
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
boolean condition = new Random().nextBoolean();
return condition ? new FlowExecutionStatus("SUCCESS") : new FlowExecutionStatus("FAILURE");
}
}
🧱 Define Conditional Job Flow
@Bean
public Job conditionalJob() {
return jobBuilderFactory.get("conditionalJob")
.start(startStep())
.next(decider())
.on("SUCCESS").to(successStep())
.from(decider())
.on("FAILURE").to(failureStep())
.end()
.build();
}
@Bean
public JobExecutionDecider decider() {
return new RandomDecider();
}
🚀 REST Controller to Trigger Job
@RestController
@RequestMapping("/job")
public class JobLauncherController {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job conditionalJob;
@GetMapping("/launch-conditional")
public String launchJob() throws Exception {
JobParameters params = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
jobLauncher.run(conditionalJob, params);
return "Conditional Job Launched!";
}
}
📌 Output
Each time you hit GET /job/launch-conditional
, it randomly triggers either the success path or failure path after executing the start step.
🧠 Why Use Conditional Flows?
- To dynamically control job behavior at runtime
- To handle retry logic and alternate paths
- To avoid unnecessary execution of all steps
✅ Summary
In this post, you learned how to configure conditional flows in Spring Batch using:
- Step-to-step transition with
.on().to()
logic - Custom
JobExecutionDecider
to dynamically route execution - Launching and testing via REST endpoint
This setup adds flexibility to your batch jobs and helps in implementing complex processing flows easily.
Subscribe to our YouTube channel: Spring Java Lab for practical tutorials on Spring Batch, Boot, and more!