Commit 091cdddc authored by Andy Wilkinson's avatar Andy Wilkinson

Merge pull request #17375 from nosan

* gh-17375:
  Polish "Add support for configuring a Batch-specific DataSource"
  Add support for configuring a Batch-specific DataSource

Closes gh-17375
parents f7850ef8 072453bf
...@@ -76,8 +76,10 @@ public class BatchAutoConfiguration { ...@@ -76,8 +76,10 @@ public class BatchAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnBean(DataSource.class) @ConditionalOnBean(DataSource.class)
public BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource, ResourceLoader resourceLoader) { public BatchDataSourceInitializer batchDataSourceInitializer(DataSource dataSource,
return new BatchDataSourceInitializer(dataSource, resourceLoader, this.properties); @BatchDataSource ObjectProvider<DataSource> batchDataSource, ResourceLoader resourceLoader) {
return new BatchDataSourceInitializer(batchDataSource.getIfAvailable(() -> dataSource), resourceLoader,
this.properties);
} }
@Bean @Bean
......
...@@ -45,8 +45,10 @@ class BatchConfigurerConfiguration { ...@@ -45,8 +45,10 @@ class BatchConfigurerConfiguration {
@Bean @Bean
BasicBatchConfigurer batchConfigurer(BatchProperties properties, DataSource dataSource, BasicBatchConfigurer batchConfigurer(BatchProperties properties, DataSource dataSource,
@BatchDataSource ObjectProvider<DataSource> batchDataSource,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) { ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
return new BasicBatchConfigurer(properties, dataSource, transactionManagerCustomizers.getIfAvailable()); return new BasicBatchConfigurer(properties, batchDataSource.getIfAvailable(() -> dataSource),
transactionManagerCustomizers.getIfAvailable());
} }
} }
...@@ -58,10 +60,11 @@ class BatchConfigurerConfiguration { ...@@ -58,10 +60,11 @@ class BatchConfigurerConfiguration {
@Bean @Bean
JpaBatchConfigurer batchConfigurer(BatchProperties properties, DataSource dataSource, JpaBatchConfigurer batchConfigurer(BatchProperties properties, DataSource dataSource,
@BatchDataSource ObjectProvider<DataSource> batchDataSource,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers,
EntityManagerFactory entityManagerFactory) { EntityManagerFactory entityManagerFactory) {
return new JpaBatchConfigurer(properties, dataSource, transactionManagerCustomizers.getIfAvailable(), return new JpaBatchConfigurer(properties, batchDataSource.getIfAvailable(() -> dataSource),
entityManagerFactory); transactionManagerCustomizers.getIfAvailable(), entityManagerFactory);
} }
} }
......
/*
* 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 java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
/**
* Qualifier annotation for a DataSource to be injected into Batch auto-configuration. Can
* be used on a secondary data source, if there is another one marked as
* {@link Primary @Primary}.
*
* @author Dmytro Nosan
* @since 2.2.0
*/
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Qualifier
public @interface BatchDataSource {
}
...@@ -49,10 +49,12 @@ import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfigurati ...@@ -49,10 +49,12 @@ import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfigurati
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.test.City; import org.springframework.boot.autoconfigure.orm.jpa.test.City;
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.DataSourceInitializationMode; import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
...@@ -233,6 +235,37 @@ class BatchAutoConfigurationTests { ...@@ -233,6 +235,37 @@ class BatchAutoConfigurationTests {
}); });
} }
@Test
void testBatchDataSource() {
this.contextRunner.withUserConfiguration(TestConfiguration.class, BatchDataSourceConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(BatchConfigurer.class)
.hasSingleBean(BatchDataSourceInitializer.class).hasBean("batchDataSource");
DataSource batchDataSource = context.getBean("batchDataSource", DataSource.class);
assertThat(context.getBean(BatchConfigurer.class)).hasFieldOrPropertyWithValue("dataSource",
batchDataSource);
assertThat(context.getBean(BatchDataSourceInitializer.class))
.hasFieldOrPropertyWithValue("dataSource", batchDataSource);
});
}
@Configuration(proxyBeanMethods = false)
protected static class BatchDataSourceConfiguration {
@Bean
@Primary
public DataSource normalDataSource() {
return DataSourceBuilder.create().url("jdbc:hsqldb:mem:normal").username("sa").build();
}
@BatchDataSource
@Bean
public DataSource batchDataSource() {
return DataSourceBuilder.create().url("jdbc:hsqldb:mem:batchdatasource").username("sa").build();
}
}
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
static class EmptyConfiguration { static class EmptyConfiguration {
......
...@@ -2429,9 +2429,13 @@ other factory that your application defines, if any. ...@@ -2429,9 +2429,13 @@ other factory that your application defines, if any.
This section answers questions that arise from using Spring Batch with Spring Boot. This section answers questions that arise from using Spring Batch with Spring Boot.
NOTE: By default, batch applications require a `DataSource` to store job details. If you NOTE: By default, batch applications require a `DataSource` to store job details.
want to deviate from that, you need to implement `BatchConfigurer`. See Batch autowires a single `DataSource` in your context and uses that for processing. To
{spring-batch-javadoc}/core/configuration/annotation/EnableBatchProcessing.html[The have Batch use a `DataSource` other than the application’s main `DataSource`, declare a
`DataSource` bean, annotating its `@Bean` method with `@BatchDataSource`. If you do so and
want two data sources, remember to create another one and mark it as `@Primary`. To take
greater control, implement `BatchConfigurer`. See
{spring-batch-javadoc}/core/configuration/annotation/EnableBatchProcessing.html[the
Javadoc of `@EnableBatchProcessing`] for more details. Javadoc of `@EnableBatchProcessing`] for more details.
For more about Spring Batch, see the https://projects.spring.io/spring-batch/[Spring Batch For more about Spring Batch, see the https://projects.spring.io/spring-batch/[Spring Batch
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment