How can I customize Spring Batch's DefaultBatchConfiguration without breaking the autoconfiguration provided by Spring Boot in SpringBootBatchConfiguration?
I am using a Spring Batch job in a Spring Boot application, with the following configuration:
@Configuration
public class MyJobConfiguration {
@Bean
public Tasklet myTasklet() {
return (contribution, chunkContext) -> {
System.out.println("execute myTasklet");
return RepeatStatus.FINISHED;
};
}
@Bean
public Step myStep(JobRepository jobRepository, Tasklet myTasklet, PlatformTransactionManager transactionManager) {
return new StepBuilder("myStep", jobRepository)
.tasklet(myTasklet, transactionManager)
.build();
}
@Bean
public Job myJob(JobRepository jobRepository, Step myStep) {
return new JobBuilder("myJob", jobRepository)
.start(myStep)
.build();
}
}
I test the job with @SpringBatchTest like so:
@SpringBatchTest
@ContextConfiguration(classes = MyJobConfiguration.class)
@EnableAutoConfiguration
class MyJobConfigurationTest {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Autowired
private JobRepositoryTestUtils jobRepositoryTestUtils;
@BeforeEach
public void setup(@Autowired Job jobUnderTest) {
this.jobLauncherTestUtils.setJob(jobUnderTest); // this is optional if the job is unique
this.jobRepositoryTestUtils.removeJobExecutions();
}
@Test
public void testMyJob() throws Exception {
// given
JobParameters jobParameters = this.jobLauncherTestUtils.getUniqueJobParameters();
// when
JobExecution jobExecution = this.jobLauncherTestUtils.launchJob(jobParameters);
// then
Assertions.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
}
}
This is pretty standard and it works as expected. As can be seen from the annotation @EnableAutoConfiguration, it makes use of Spring Boot's autoconfiguration for Spring Batch, which for instance guarantees that the database schema is initialized in the in-memory database for the test.
I would like to customize the batch configuration to allow asynchronous job execution. I modified my configuration in the following way:
@Configuration
public class MyJobConfiguration extends DefaultBatchConfiguration {
public static final int MAX_BATCH_TASK_EXECUTOR_POOL_SIZE = 20;
@Override
public TaskExecutor getTaskExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setMaxPoolSize(MAX_BATCH_TASK_EXECUTOR_POOL_SIZE);
threadPoolTaskExecutor.afterPropertiesSet();
return threadPoolTaskExecutor;
}
The javadoc of DefaultBatchConfiguration says:
Customization is possible by extending the class and overriding getters.
That's why I chose this approach. However, this seems to knock out Spring Boot's autoconfiguration for Spring Batch. The spring batch test fails because the database schema initialization is not done anymore. The condition evaluation report confirms this.
Is it possible to customize the Spring Batch configuration this way?
When relying on Spring Boot's autoconfiguration for Spring Batch, is there another way to add customizations?
Is it preferrable to configure additional joblaunchers and not customize the behaviour of the default joblauncher?
Instead of extending DefaultBatchConfiguration, you can define custom beans for specific components you want to customize. For example, you can define a custom TaskExecutor bean without extending DefaultBatchConfiguration. This allows you to retain other autoconfigured beans provided by Spring Boot.