In this post, I am going to explain how to develop simple job using Spring Batch.
Job is a collection of steps, where each step will perform dedicated task. Steps can be executed sequentially or parallely.
As you see above image,
a. Job1 has 4 steps, where the steps will get executed sequentially.
b. Job2 has 4 steps, where step 2 and step 3 are executed parallelly.
There are two different types of steps.
a. Tasklet
Tasklet is an interface that has a method 'execute'. Whatever the code you want to execute, you can put inside execute method. You should return 'RepeatStatus.FINISHE' from execute method if the step finish execution else return RepeatStatus.CONTINUABLE
public interface Tasklet {
@Nullable
RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception;
}
b. Chunk
Chunk encapsulate list of items to be processed. Chunk based step is item based. There are 3 main components in Chunk based step.
a. ItemReader: Provide input to the step
b. ItemProcessor: Process the information. It is optional.
c. ItemWriter: Provide output to the step.
Let’s create a job with one task.
Step 1: Create a step.
@Bean
public Step step() {
return this.stepBuilderFactory.get("step1").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
System.out.println(count + ". Hello, World!");
count++;
if (count < 5) {
return RepeatStatus.CONTINUABLE;
} else {
return RepeatStatus.FINISHED;
}
}
}).build();
}
Above step prints the message "Hello, World!" 5 times to the console and finish the process.
Step 2: Create a job that will start the step created in step 1.
@Bean
public Job job() {
return this.jobBuilderFactory.get("job").start(step()).build();
}
Find the below working application.
Step 1: Create new maven project ‘spring-batch-hello-world’.
Step 2: Update pom.xml with maven dependencies.
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.batch/spring-batch-core -->
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
Right now I am not using any JPA specific functionality, but these will be used in subsequent posts.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample.app</groupId>
<artifactId>spring-batch-hello-world</artifactId>
<version>1</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.batch/spring-batch-core -->
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
</project>
Step 3: Create a package ‘com.sample.app’ and define App class like below.
App.java
package com.sample.app;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
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.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@EnableBatchProcessing
@SpringBootApplication
public class App {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
private static int count = 0;
@Bean
public Step step() {
return this.stepBuilderFactory.get("step1").tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
System.out.println(count + ". Hello, World!");
count++;
if (count < 5) {
return RepeatStatus.CONTINUABLE;
} else {
return RepeatStatus.FINISHED;
}
}
}).build();
}
@Bean
public Job job() {
return this.jobBuilderFactory.get("job").start(step()).build();
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Total project structure looks like below.
Run App.java, you will see below messages in console.
0. Hello, World! 1. Hello, World! 2. Hello, World! 3. Hello, World! 4. Hello, World! 2020-03-26 11:12:49.943 INFO 57629 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=job]] completed with the following parameters: [{}] and the following status: [COMPLETED]
No comments:
Post a Comment