Learn to create a Spring batch job (with multiple steps) with Java configuration in a Spring boot application. The example uses H2 database for persistence purposes.
1. Maven Dependencies
We need to include spring-boot-starter-batch
dependency. Spring batch relies on a job repository which is a persistent data store. So we need one DB as well. We are using H2 (in-memory database) which integrates well with Spring batch.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
2. Creating a Batch Job
In this project, we will create a simple job with 2 step tasks and execute the job to observe the logs. Job execution flow will be –
- Start job
- Execute task one
- Execute task two
- Finish job
2.1. Add Tasklets
The first step is to create a few tasks that will be run in sequence to form a job. In the Spring batch, they are implemented as 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;
public class MyTaskOne implements Tasklet {
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception
{
System.out.println("MyTaskOne start..");
// ... your code
System.out.println("MyTaskOne done..");
return RepeatStatus.FINISHED;
}
}
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;
public class MyTaskTwo implements Tasklet {
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception
{
System.out.println("MyTaskTwo start..");
// ... your code
System.out.println("MyTaskTwo done..");
return RepeatStatus.FINISHED;
}
}
2.2. Batch Job Configuration
This is the major step where you define all the job-related configurations and their execution logic.
The @EnableBatchProcessing annotation autoconfigures many useful beans that we need to create otherwise. It also configures the JobBuilderFactory and StepBuilderFactory beans.
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.howtodoinjava.demo.tasks.MyTaskOne;
import com.howtodoinjava.demo.tasks.MyTaskTwo;
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Bean
public Step stepOne(){
return steps.get("stepOne")
.tasklet(new MyTaskOne())
.build();
}
@Bean
public Step stepTwo(){
return steps.get("stepTwo")
.tasklet(new MyTaskTwo())
.build();
}
@Bean
public Job demoJob(){
return jobs.get("demoJob")
.incrementer(new RunIdIncrementer())
.start(stepOne())
.next(stepTwo())
.build();
}
}
3. Demo
Now our simple job 'demoJob'
is configured and ready to be executed. we are using CommandLineRunner
interface to execute the job automatically, with JobLauncher
, when the application is fully started.
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App implements CommandLineRunner
{
@Autowired
JobLauncher jobLauncher;
@Autowired
Job job;
public static void main(String[] args)
{
SpringApplication.run(App.class, args);
}
@Override
public void run(String... args) throws Exception
{
JobParameters params = new JobParametersBuilder()
.addString("JobID", String.valueOf(System.currentTimeMillis()))
.toJobParameters();
jobLauncher.run(job, params);
}
}
Notice the console logs.
o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=demoJob]] launched with
the following parameters: [{JobID=1530697766768}]
o.s.batch.core.job.SimpleStepHandler : Executing step: [stepOne]
MyTaskOne start..
MyTaskOne done..
o.s.batch.core.job.SimpleStepHandler : Executing step: [stepTwo]
MyTaskTwo start..
MyTaskTwo done..
o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=demoJob]] completed with
the following parameters: [{JobID=1530697766768}] and the following status: [COMPLETED]
4. Disable Auto-run of Jobs
Spring also automatically run the configured batch jobs. To disable the auto-run of jobs, we need to use spring.batch.job.enabled
property in application.properties file.
spring.batch.job.enabled=false
Happy Learning !!