This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Batch Documentation 5.2.2!

What’s new in Spring Batch 6

This section highlights the major changes in Spring Batch 6.0. For the complete list of changes, please refer to the release notes.

Spring Batch 6.0 includes the following features:

Dependencies upgrade

In this major release, the Spring dependencies are upgraded to the following versions:

  • Spring Framework 7.0

  • Spring Integration 7.0

  • Spring Data 4.0

  • Spring LDAP 4.0

  • Spring AMQP 4.0

  • Spring Kafka 4.0

  • Micrometer 1.16

Batch infrastructure configuration improvements

New annotations and classes for batch infrastructure configuration

Before v6, the @EnableBatchProcessing annotation was tied to a JDBC-based infrastructure. This is not the case anymore. Two new annotations have been introduced to configure the underlying job repository: @EnableJdbcJobRepository and @EnableMongoJobRepository.

Starting from v6, @EnableBatchProcessing allows you to configure common attributes for the batch infrastructure, while store-specific attributes can be specified with the new dedicated annotations.

Here is an example of how to use these annotations:

@EnableBatchProcessing(taskExecutorRef = "batchTaskExecutor")
@EnableJdbcJobRepository(dataSourceRef = "batchDataSource", transactionManagerRef = "batchTransactionManager")
class MyJobConfiguration {

	@Bean
	public Job job(JobRepository jobRepository) {
		return new JobBuilder("job", jobRepository)
                    // job flow omitted
                    .build();
	}
}

Similarly, the programmatic model based on DefaultBatchConfiguration has been updated by introducing two new configuration classes to define store-specific attributes: JdbcDefaultBatchConfiguration and MongoDefaultBatchConfiguration. These classes can be used to configure specific attributes of each job repository as well as other batch infrastructure beans programmatically.

Resourceless batch infrastructure by default

The DefaultBatchConfiguration class has been updated to provide a "resourceless" batch infrastructure by default (based on the ResourcelessJobRepository implementation introduced in v5.2). This means that it no longer requires an in-memory database (like H2 or HSQLDB) for the job repository, which was previously necessary for batch metadata storage.

Moreover, this change will improve the default performance of batch applications when the meta-data is not used, as the ResourcelessJobRepository does not require any database connections or transactions.

Finally, this change will help to reduce the memory footprint of batch applications, as the in-memory database is no longer required for metadata storage.

Batch infrastructure configuration simplification

Before v6, the typical configuration of a non-trivial Spring Batch application was quite complex and required a lot of beans: JobRepository, JobLauncher, JobExplorer, JobOperator, JobRegistry, JobRegistrySmartInitializingSingleton and so on. This required a lot of configuration code, like for example the need to configure the same execution context serializer on both the JobRepository and JobExplorer.

In this release, several changes have been made to simplify the batch infrastructure configuration:

  • The JobRepository now extends the JobExplorer interface, so there is no need to define a separate JobExplorer bean.

  • The JobOperator now extends the JobLauncher interface, so there is no need to define a separate JobLauncher bean.

  • The JobRegistry is now smart enough to register jobs automatically, so there is no need to define a separate JobRegistrySmartInitializingSingleton bean.

This reduces the number of beans required for a typical batch application and simplifies the configuration code.

New implementation of the chunk-oriented processing model

This is not a new feature, but rather a new implementation of the chunk-oriented processing model. This new implementation was introduced as an experimental addition in version 5.1, and is now available as stable in version 6.0.

The new implementation is provided in the ChunkOrientedStep class, which is a replacement for the ChunkOrientedTasklet / TaskletStep classes.

Here is an example of how to define a ChunkOrientedStep by using its builder:

@Bean
public Step chunkOrientedStep(JobRepository jobRepository, JdbcTransactionManager transactionManager,
        ItemReader<Person> itemReader, ItemProcessor<Person, Person> itemProcessor, ItemWriter<Person> itemWriter) {
    int chunkSize = 100;
    return new ChunkOrientedStepBuilder<Person, Person>(jobRepository, transactionManager, chunkSize)
        .reader(itemReader)
        .processor(itemProcessor)
        .writer(itemWriter)
        .build();
}

Moreover, fault-tolerance features were adapted as follows:

  • The retry feature is now based on the retry functionality introduced in Spring Framework 7, instead of the previous Spring Retry library

  • The skip feature has been slightly adapted to the new implementation, which is now only based entirely on the SkipPolicy interface

Here is a quick example of how to use the retry and skip features with the new ChunkOrientedStep:

@Bean
public Step faulTolerantChunkOrientedStep(JobRepository jobRepository, JdbcTransactionManager transactionManager,
        ItemReader<Person> itemReader, ItemProcessor<Person, Person> itemProcessor, ItemWriter<Person> itemWriter) {

    // retry policy configuration
    int maxAttempts = 10;
    var retrybaleExceptions = Set.of(TransientException.class);
    RetryPolicy retryPolicy = RetryPolicy.builder()
        .maxAttempts(maxAttempts)
        .includes(retrybaleExceptions)
        .build();

    // skip policy configuration
    int skipLimit = 50;
    var skippableExceptions = Set.of(FlatFileParseException.class);
    SkipPolicy skipPolicy = new LimitCheckingItemSkipPolicy(skipLimit, skippableExceptions);

    // step configuration
    int chunkSize = 100;
    return new ChunkOrientedStepBuilder<Person, Person>(jobRepository, transactionManager, chunkSize)
        .reader(itemReader)
        .processor(itemProcessor)
        .writer(itemWriter)
        .faultTolerant()
        .retryPolicy(retryPolicy)
        .skipPolicy(skipPolicy)
        .build();
}

Please refer to the migration guide for more details on how to migrate from the previous implementation to the new one.

New command line operator

Spring Batch provided a CommandLineJobRunner since version 1. While this runner served its purpose well over the years, it started to show some limitations when it comes to extensibility and customisation. Many issues like static initialisation, non-standard way of handling options and parameters, lack of extensibility, etc have been reported.

Moreover, all these issues made it impossible to reuse that runner in Spring Boot, which resulted in duplicate code in both projects as well behaviour divergence (like job parameters incrementer behaviour differences) that is confusing to many users.

This release introduces a modern version of CommandLineJobRunner, named CommandLineJobOperator, that allows you to operate batch jobs from the command line (start, stop, restart and so on) and that is customisable, extensible and updated to the new changes introduced in Spring Batch 6.

Ability to recover failed job executions

Prior to this release, if a job execution fails abruptly, it was not possible to recover it without a manual database update. This was error-prone and not consistent across different job repositories (as it required a few SQL statements for JDBC databases and some custom statements for NoSQL stores).

This release introduces a new method named recover in the JobOperator interface that allows you to recover failed job executions consistently across all job repositories.

Deprecations and pruning

As with any major release, some features have been deprecated or removed in Spring Batch 6.0. The following changes are worth noting:

  • All deprecated APIs and features from previous versions have been removed

  • Modular configuration through @EnableBatchProcessing(modular = true) has been deprecated

  • Several APIs have been deprecated in this version, in order to simplify the core API and reduce its scope

Fore more details, please refer to the migration guide.