Step‑by‑Step Spring Batch Hello World Job with Spring Boot
This tutorial walks you through building a simple Spring Batch Hello World job using Spring Boot and Maven, covering the framework basics, project setup, Maven configuration, entity modeling, job and step configuration, data processing, testing, and how to run the example to generate greeting output.
1. Spring Batch Framework Overview
Spring Batch processes large volumes of data in a batch job. A Job consists of one or more Step objects, each typically reading data with an ItemReader, transforming it with an ItemProcessor, and writing it with an ItemWriter. The JobLauncher starts a job, while the JobRepository stores job metadata.
2. Example Overview
The example uses Spring Batch 4.1, Spring Boot 2.1, and Maven 3.6. The project follows a standard Maven layout.
3. Maven Configuration
The Maven pom.xml includes the Spring Boot parent, the spring-boot-starter-batch and spring-boot-starter-test dependencies, as well as spring-batch-test for testing. The spring-boot-maven-plugin builds an executable uber‑jar.
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.codenotfound</groupId>
<artifactId>spring-batch-hello-world</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>4. Spring Boot Configuration
Create a SpringBatchApplication class annotated with @SpringBootApplication and exclude DataSourceAutoConfiguration so that Spring Batch uses an in‑memory job repository.
package com.codenotfound;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SpringBatchApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBatchApplication.class, args);
}
}Note: @SpringBootApplication combines @Configuration , @EnableAutoConfiguration and @ComponentScan .
5. Entity Model
The input CSV rows are mapped to a simple POJO named Person with firstName and lastName fields.
package com.codenotfound.model;
public class Person {
private String firstName;
private String lastName;
public Person() {}
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
@Override
public String toString() {
return firstName + " " + lastName;
}
}6. Spring Batch Job Configuration
First, a BatchConfig class extends DefaultBatchConfigurer and overrides setDataSource to keep the default map‑based JobRepository.
package com.codenotfound.batch;
import javax.sql.DataSource;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
public class BatchConfig extends DefaultBatchConfigurer {
@Override
public void setDataSource(DataSource dataSource) {
// use map‑based JobRepository (no DB)
}
}Next, HelloWorldJobConfig defines the Job and Step beans, a FlatFileItemReader for the CSV, a PersonItemProcessor, and a FlatFileItemWriter that writes greetings to greeting.txt.
package com.codenotfound.batch;
import com.codenotfound.model.Person;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.batch.item.file.transform.PassThroughLineAggregator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
@Configuration
public class HelloWorldJobConfig {
@Bean
public Job helloWorldJob(JobBuilderFactory jobBuilders, StepBuilderFactory stepBuilders) {
return jobBuilders.get("helloWorldJob")
.start(helloWorldStep(stepBuilders))
.build();
}
@Bean
public Step helloWorldStep(StepBuilderFactory stepBuilders) {
return stepBuilders.get("helloWorldStep")
.<Person, String>chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
@Bean
public FlatFileItemReader<Person> reader() {
return new FlatFileItemReaderBuilder<Person>()
.name("personItemReader")
.resource(new ClassPathResource("csv/persons.csv"))
.delimited()
.names("firstName", "lastName")
.targetType(Person.class)
.build();
}
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean
public FlatFileItemWriter<String> writer() {
return new FlatFileItemWriterBuilder<String>()
.name("greetingItemWriter")
.resource(new FileSystemResource("target/test-outputs/greetings.txt"))
.lineAggregator(new PassThroughLineAggregator<>())
.build();
}
}7. Data Processing
The PersonItemProcessor implements ItemProcessor<Person, String> and converts a Person into a greeting string.
package com.codenotfound.batch;
import com.codenotfound.model.Person;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
public class PersonItemProcessor implements ItemProcessor<Person, String> {
private static final Logger LOGGER = LoggerFactory.getLogger(PersonItemProcessor.class);
@Override
public String process(Person person) throws Exception {
String greeting = "Hello " + person.getFirstName() + " " + person.getLastName() + "!";
LOGGER.info("converting '{}' into '{}'", person, greeting);
return greeting;
}
}8. Testing the Batch Job
A Spring Boot test uses JobLauncherTestUtils to launch the job and asserts that the exit status is COMPLETED.
package com.codenotfound;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {SpringBatchApplicationTests.BatchTestConfig.class})
public class SpringBatchApplicationTests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
public void testHelloWorldJob() throws Exception {
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
assertThat(jobExecution.getExitStatus().getExitCode()).isEqualTo("COMPLETED");
}
@Configuration
@Import({BatchConfig.class, HelloWorldJobConfig.class})
static class BatchTestConfig {
@Autowired
private Job helloWorldJob;
@Bean
public JobLauncherTestUtils jobLauncherTestUtils() {
JobLauncherTestUtils utils = new JobLauncherTestUtils();
utils.setJob(helloWorldJob);
return utils;
}
}
}9. Running the Example
Execute the test (or the job) with Maven: mvn test The job reads persons.csv, creates greetings, and writes them to target/test-outputs/greetings.txt. The resulting file contains:
Hello John Doe!
Hello Jane Doe!For the full source code, visit the original tutorial page.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
