Wednesday 18 November 2020

Spring Batch: Hello World Application

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]


Previous                                                    Next                                                    Home

No comments:

Post a Comment