From 02bea78229fff39dd0dcce66a2e2de91b330d6cb Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 8 Jul 2019 15:35:16 +0100 Subject: [PATCH] Retain as much Batch auto-config as possible without Spring JDBC Closes gh-17451 --- .../batch/BatchAutoConfiguration.java | 45 +++++----- ...atchAutoConfigurationWithoutJdbcTests.java | 87 +++++++++++++++++++ 2 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJdbcTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java index 21e1d2ecde..c68302c443 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java @@ -39,7 +39,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.io.ResourceLoader; -import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.datasource.init.DatabasePopulator; import org.springframework.util.StringUtils; /** @@ -60,37 +60,20 @@ import org.springframework.util.StringUtils; * @since 1.0.0 */ @Configuration -@ConditionalOnClass({ JobLauncher.class, DataSource.class, JdbcOperations.class }) +@ConditionalOnClass({ JobLauncher.class, DataSource.class }) @AutoConfigureAfter(HibernateJpaAutoConfiguration.class) @ConditionalOnBean(JobLauncher.class) @EnableConfigurationProperties(BatchProperties.class) @Import(BatchConfigurerConfiguration.class) public class BatchAutoConfiguration { - private final BatchProperties properties; - - private final JobParametersConverter jobParametersConverter; - - public BatchAutoConfiguration(BatchProperties properties, - ObjectProvider jobParametersConverter) { - this.properties = properties; - this.jobParametersConverter = jobParametersConverter.getIfAvailable(); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBean(DataSource.class) - public BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader) { - return new BatchDataSourceInitializer(dataSource, resourceLoader, this.properties); - } - @Bean @ConditionalOnMissingBean @ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true) public JobLauncherCommandLineRunner jobLauncherCommandLineRunner(JobLauncher jobLauncher, JobExplorer jobExplorer, - JobRepository jobRepository) { + JobRepository jobRepository, BatchProperties properties) { JobLauncherCommandLineRunner runner = new JobLauncherCommandLineRunner(jobLauncher, jobExplorer, jobRepository); - String jobNames = this.properties.getJob().getNames(); + String jobNames = properties.getJob().getNames(); if (StringUtils.hasText(jobNames)) { runner.setJobNames(jobNames); } @@ -106,16 +89,28 @@ public class BatchAutoConfiguration { @Bean @ConditionalOnMissingBean(JobOperator.class) public SimpleJobOperator jobOperator(JobExplorer jobExplorer, JobLauncher jobLauncher, - ListableJobLocator jobRegistry, JobRepository jobRepository) throws Exception { + ListableJobLocator jobRegistry, JobRepository jobRepository, + ObjectProvider jobParametersConverter) { SimpleJobOperator factory = new SimpleJobOperator(); factory.setJobExplorer(jobExplorer); factory.setJobLauncher(jobLauncher); factory.setJobRegistry(jobRegistry); factory.setJobRepository(jobRepository); - if (this.jobParametersConverter != null) { - factory.setJobParametersConverter(this.jobParametersConverter); - } + jobParametersConverter.ifAvailable(factory::setJobParametersConverter); return factory; } + @ConditionalOnBean(DataSource.class) + @ConditionalOnClass(DatabasePopulator.class) + static class DataSourceInitializerConfiguration { + + @Bean + @ConditionalOnMissingBean + public BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource, + ResourceLoader resourceLoader, BatchProperties properties) { + return new BatchDataSourceInitializer(dataSource, resourceLoader, properties); + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJdbcTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJdbcTests.java new file mode 100644 index 0000000000..87bff520fe --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfigurationWithoutJdbcTests.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.batch; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.batch.core.configuration.annotation.BatchConfigurer; +import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing; +import org.springframework.batch.core.explore.JobExplorer; +import org.springframework.batch.core.launch.JobLauncher; +import org.springframework.batch.core.launch.support.SimpleJobOperator; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions; +import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.PlatformTransactionManager; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link BatchAutoConfiguration} when Spring JDBC is not on the classpath. + * + * @author Andy Wilkinson + */ +@RunWith(ModifiedClassPathRunner.class) +@ClassPathExclusions("spring-jdbc-*.jar") +public class BatchAutoConfigurationWithoutJdbcTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(BatchAutoConfiguration.class, TransactionAutoConfiguration.class)) + .withUserConfiguration(BatchConfiguration.class); + + @Test + public void whenThereIsNoJdbcOnTheClasspathThenComponentsAreStillAutoConfigured() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(JobLauncherCommandLineRunner.class); + assertThat(context).hasSingleBean(JobExecutionExitCodeGenerator.class); + assertThat(context).hasSingleBean(SimpleJobOperator.class); + }); + } + + @Configuration + @EnableBatchProcessing + static class BatchConfiguration implements BatchConfigurer { + + @Override + public JobRepository getJobRepository() throws Exception { + return mock(JobRepository.class); + } + + @Override + public PlatformTransactionManager getTransactionManager() throws Exception { + return mock(PlatformTransactionManager.class); + } + + @Override + public JobLauncher getJobLauncher() throws Exception { + return mock(JobLauncher.class); + } + + @Override + public JobExplorer getJobExplorer() throws Exception { + return mock(JobExplorer.class); + } + + } + +}