What Spring Batch is & running a first job
|
This section documents the current Spring Batch line — 6.0.x, on Spring Framework 7 and Spring Boot 4.1.x, with a Java 17+ baseline — as published at the Spring Batch reference documentation. No specific patch version is pinned. Some surfaces (Spring Cloud Task and Spring Cloud Data Flow orchestration, the deployer-based partition handler, and JSR-352) are linked, not documented in depth. This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. |
Spring Batch is a lightweight framework for finite, bounded bulk processing: reading a large but known quantity of input, doing something to each item, and writing the result — restartably, transactionally, and with a full audit trail. This page places the framework, lists its modules, and walks through a first runnable job.
A framework for finite, bounded processing
A batch job has a beginning and an end. It processes a finite input — yesterday’s transactions, a delivered file, the rows added since the last watermark — and then terminates. That boundedness is what lets Spring Batch offer the guarantees it does: a job that will end is a job whose progress can be recorded, whose failure can be resumed from the last commit point, and whose outcome can be reported.
Spring Batch supplies the parts that every such program otherwise re-invents:
-
a domain language —
Job,Step,ItemReader,ItemProcessor,ItemWriter— so the structure of a batch program is explicit rather than buried in amain()method; -
a
JobRepositorythat persists what ran, with which parameters, how far it got, and how it ended; -
chunk-oriented processing, which turns "read a million rows" into "read, process and write N rows per transaction", bounding memory and giving restart a granularity;
-
fault tolerance — skip, retry and rollback policies applied declaratively rather than hand-coded;
-
scaling strategies (multi-threaded steps, parallel flows, partitioning, remote chunking) that leave the business logic untouched.
For the framework’s own overview see Spring Batch Introduction.
What Spring Batch is not
Spring Batch is not a scheduler. It has no cron table, no calendar, no concept of "run this at 02:00". It
provides the machinery to run a job and to know what happened; deciding when to run it is somebody else’s
job — Unix cron, Quartz, Control-M, an enterprise scheduler, a Kubernetes CronJob, or a message arriving
on a queue. Pairing the two is covered in
Running a job and
Cloud-native batch.
It is also not a streaming framework: an unbounded, never-ending source of events is a different problem with different tools. And it is not an ETL product with a graphical designer — jobs are ordinary Spring beans written in Java.
A short history
Spring Batch began in 2007 as a collaboration between Accenture, which contributed decades of in-house batch architecture experience, and SpringSource (then Interface21), which contributed the Spring programming model. Accenture donated its batch frameworks; the result was released as an open-source project and has been part of the Spring portfolio ever since.
The JSR-352 (jakarta.batch, "Batch Applications for the Java Platform") specification was later standardised
with heavy influence from Spring Batch, and Dave Syer — Spring Batch’s original lead — was on the expert
group. Spring Batch’s own API remains the richer of the two; JSR-352 is linked, not documented in depth
here.
Module layout
Spring Batch ships as a small set of artifacts:
| Module | Contains |
|---|---|
|
The domain and its runtime: |
|
The reusable plumbing: the |
|
Test support: |
|
The bridge to Spring Integration: launching jobs from messages, async processing, remote chunking and remote partitioning. |
|
The Spring Boot starter that pulls in |
Under Spring Boot, one starter is normally all that is declared — Boot’s dependency management supplies the version:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
The release line
These pages track Spring Batch 6.0.x, which runs on Spring Framework 7 and is the line shipped by Spring Boot 4.1.x, with a Java 17+ baseline. The headline changes relative to the previous generation are summarised in What’s new in Spring Batch 6.0 and noted on the individual pages where they matter:
-
JobBuilderFactoryandStepBuilderFactoryare gone — constructnew JobBuilder(name, jobRepository)andnew StepBuilder(name, jobRepository)directly; -
BatchConfigureris gone — extendDefaultBatchConfigurationinstead (Infrastructure configuration); -
javax.becamejakarta.; -
the infrastructure defaults are now resourceless — no database is required to run a job;
-
JobRepositoryabsorbedJobExplorer, andJobOperatorabsorbedJobLauncher; -
retry is built on Spring Framework 7’s core retry support rather than the separate Spring Retry library (Fault tolerance: skip & retry);
-
CommandLineJobRunnerwas replaced byCommandLineJobOperator; -
JUnit 4 support was dropped — tests are JUnit Jupiter only (Testing batch jobs).
A first runnable job
The smallest useful job is a single tasklet step: one unit of work that runs inside one transaction and
reports that it is finished. The JobRepository is auto-configured by Spring Boot, so it can simply be
injected into the configuration class.
package com.example.batch;
import org.springframework.batch.core.job.Job;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.Step;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class HelloWorldJobConfiguration {
@Bean
public Step helloStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("helloStep", jobRepository)
.tasklet((contribution, chunkContext) -> {
System.out.println("Hello, Spring Batch!");
return RepeatStatus.FINISHED;
}, transactionManager)
.build();
}
@Bean
public Job helloWorldJob(JobRepository jobRepository, Step helloStep) {
return new JobBuilder("helloWorldJob", jobRepository)
.start(helloStep)
.build();
}
}
Nothing else is required: no @EnableBatchProcessing. Under Spring Boot that annotation actively disables
the batch auto-configuration, which is why it is left off here — see
Infrastructure configuration.
Running it
Spring Boot registers a JobLauncherApplicationRunner that runs jobs at startup. Name the job to run and pass
parameters as --key=value arguments:
spring:
batch:
job:
name: helloWorldJob
# equivalent, and the switch that turns startup execution off entirely
spring.batch.job.name=helloWorldJob
spring.batch.job.enabled=true
java -jar batch-app.jar --spring.batch.job.name=helloWorldJob run.date=2026-01-31
For an application that should not run a job on startup — one that launches jobs on demand from an
endpoint, a scheduler, or a message — set spring.batch.job.enabled=false and launch through the
JobOperator; both styles are covered in Running a job.
The Spring Boot side of this — the starter, the auto-configured job repository and data source, the
spring.batch.* properties — is documented at
Batch Applications and, in this site, on the
shorter Spring Batch (SpringBoot Reference) page.
Where to go next
-
Jobs, instances & parameters — what a job instance is, why parameters decide identity, and how restart works.
-
Chunk-oriented processing — the read/process/write loop that does the actual bulk work.
-
Architecture & processing strategies — the layering, and how to choose a processing strategy before writing code.