From e0adacbeae58bb647468ddd6dfa6a8940b749b8b Mon Sep 17 00:00:00 2001 From: Kazuki Shimizu Date: Mon, 25 Jul 2016 16:52:51 -0700 Subject: [PATCH 1/2] Add TransactionManager only on single DataSource Update auto-configuration logic so that a `DataSourceTransactionManager` is only added when there is a single candidate DataSource bean. See gh-6449 --- ...ceTransactionManagerAutoConfiguration.java | 4 +- ...nsactionManagerAutoConfigurationTests.java | 22 +++++++++ .../jdbc/MultiDataSourceConfiguration.java | 43 ++++++++++++++++++ ...tiDataSourceUsingPrimaryConfiguration.java | 45 +++++++++++++++++++ .../autoconfigure/jdbc/TestDataSource.java | 35 +++++++++++++++ 5 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceConfiguration.java create mode 100644 spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceUsingPrimaryConfiguration.java create mode 100644 spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestDataSource.java diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java index bec6eef8e4..d5feaf1352 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java @@ -20,9 +20,9 @@ import javax.sql.DataSource; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -46,7 +46,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; public class DataSourceTransactionManagerAutoConfiguration { @Configuration - @ConditionalOnBean(DataSource.class) + @ConditionalOnSingleCandidate(DataSource.class) static class DataSourceTransactionManagerConfiguration { private final DataSource dataSource; diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java index cb62425feb..93b44a1414 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfigurationTests.java @@ -36,6 +36,7 @@ import static org.mockito.Mockito.mock; * * @author Dave Syer * @author Stephane Nicoll + * @author Kazuki Shimizu */ public class DataSourceTransactionManagerAutoConfigurationTests { @@ -84,6 +85,27 @@ public class DataSourceTransactionManagerAutoConfigurationTests { .isEqualTo(this.context.getBean("myTransactionManager")); } + @Test + public void testMultiDataSource() throws Exception { + this.context.register(MultiDataSourceConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class); + this.context.refresh(); + assertThat(this.context.getBeansOfType(PlatformTransactionManager.class)) + .isEmpty(); + assertThat(this.context.getBean(AbstractTransactionManagementConfiguration.class)) + .isNotNull(); + } + + @Test + public void testMultiDataSourceUsingPrimary() throws Exception { + this.context.register(MultiDataSourceUsingPrimaryConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class); + this.context.refresh(); + assertThat(this.context.getBean(DataSourceTransactionManager.class)).isNotNull(); + assertThat(this.context.getBean(AbstractTransactionManagementConfiguration.class)) + .isNotNull(); + } + @EnableTransactionManagement protected static class SwitchTransactionsOn { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceConfiguration.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceConfiguration.java new file mode 100644 index 0000000000..39e4659385 --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceConfiguration.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2016 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 + * + * http://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.jdbc; + +import javax.sql.DataSource; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration for multiple {@link DataSource}. + * + * @author Phillip Webb + * @author Kazuki Shimizu + */ +@Configuration +class MultiDataSourceConfiguration { + + @Bean + public DataSource test1DataSource() { + return new TestDataSource("test1"); + } + + @Bean + public DataSource test2DataSource() { + return new TestDataSource("test2"); + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceUsingPrimaryConfiguration.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceUsingPrimaryConfiguration.java new file mode 100644 index 0000000000..938fe8c5df --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/MultiDataSourceUsingPrimaryConfiguration.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-2016 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 + * + * http://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.jdbc; + +import javax.sql.DataSource; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +/** + * Configuration for multiple {@link DataSource} (one being {@code @Primary}. + * + * @author Phillip Webb + * @author Kazuki Shimizu + */ +@Configuration +class MultiDataSourceUsingPrimaryConfiguration { + + @Bean + @Primary + public DataSource test1DataSource() { + return new TestDataSource("test1"); + } + + @Bean + public DataSource test2DataSource() { + return new TestDataSource("test2"); + } + +} diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestDataSource.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestDataSource.java new file mode 100644 index 0000000000..8e69d63ced --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TestDataSource.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-2016 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 + * + * http://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.jdbc; + +import org.apache.commons.dbcp.BasicDataSource; + +/** + * {@link BasicDataSource} used for testing. + * + * @author Phillip Webb + * @author Kazuki Shimizu + */ +public class TestDataSource extends BasicDataSource { + + public TestDataSource(String name) { + setDriverClassName("org.hsqldb.jdbcDriver"); + setUrl("jdbc:hsqldb:target/" + name); + setUsername("sa"); + } + +} From 5ecb68b226381c6a2557c7b397183d5e30dc6e42 Mon Sep 17 00:00:00 2001 From: Kazuki Shimizu Date: Mon, 25 Jul 2016 16:55:07 -0700 Subject: [PATCH 2/2] Add JdbcTemplate only on single DataSource Update auto-configuration logic so that a `JdbcTemplate` is only added when there is a single candidate DataSource bean. Closes gh-6449 --- .../jdbc/DataSourceAutoConfiguration.java | 27 --- .../jdbc/JdbcTemplateAutoConfiguration.java | 67 +++++++ .../main/resources/META-INF/spring.factories | 1 + .../DataSourceAutoConfigurationTests.java | 31 ---- .../jdbc/DataSourceInitializerTests.java | 6 +- .../JdbcTemplateAutoConfigurationTests.java | 164 ++++++++++++++++++ 6 files changed, 235 insertions(+), 61 deletions(-) create mode 100644 spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfiguration.java create mode 100644 spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfigurationTests.java diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java index d909a62bb6..d6936471bd 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java @@ -47,10 +47,6 @@ import org.springframework.context.annotation.Import; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.type.AnnotatedTypeMetadata; -import org.springframework.jdbc.core.JdbcOperations; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; /** @@ -108,29 +104,6 @@ public class DataSourceAutoConfiguration { } - @Configuration - @Conditional(DataSourceAutoConfiguration.DataSourceAvailableCondition.class) - protected static class JdbcTemplateConfiguration { - - private final DataSource dataSource; - - public JdbcTemplateConfiguration(DataSource dataSource) { - this.dataSource = dataSource; - } - - @Bean - @ConditionalOnMissingBean(JdbcOperations.class) - public JdbcTemplate jdbcTemplate() { - return new JdbcTemplate(this.dataSource); - } - - @Bean - @ConditionalOnMissingBean(NamedParameterJdbcOperations.class) - public NamedParameterJdbcTemplate namedParameterJdbcTemplate() { - return new NamedParameterJdbcTemplate(this.dataSource); - } - } - @Configuration @ConditionalOnProperty(prefix = "spring.datasource", name = "jmx-enabled") @ConditionalOnClass(name = "org.apache.tomcat.jdbc.pool.DataSourceProxy") diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfiguration.java new file mode 100644 index 0000000000..7040e36795 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfiguration.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2016 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 + * + * http://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.jdbc; + +import javax.sql.DataSource; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for {@link JdbcTemplate} and + * {@link NamedParameterJdbcTemplate}. + * + * @author Dave Syer + * @author Phillip Webb + * @author Stephane Nicoll + * @author Kazuki Shimizu + * @since 1.4.0 + */ +@Configuration +@ConditionalOnClass(DataSource.class) +@ConditionalOnSingleCandidate(DataSource.class) +@AutoConfigureAfter(DataSourceAutoConfiguration.class) +public class JdbcTemplateAutoConfiguration { + + private final DataSource dataSource; + + public JdbcTemplateAutoConfiguration(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Bean + @ConditionalOnMissingBean(JdbcOperations.class) + public JdbcTemplate jdbcTemplate() { + return new JdbcTemplate(this.dataSource); + } + + @Bean + @ConditionalOnMissingBean(NamedParameterJdbcOperations.class) + public NamedParameterJdbcTemplate namedParameterJdbcTemplate() { + return new NamedParameterJdbcTemplate(this.dataSource); + } + +} diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 5bf76dac0f..e6ff4b7b66 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -49,6 +49,7 @@ org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\ org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\ org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ +org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\ diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java index 3f398fded6..915da4743f 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfigurationTests.java @@ -42,8 +42,6 @@ import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -228,35 +226,6 @@ public class DataSourceAutoConfigurationTests { assertThat(dataSource).isInstanceOf(BasicDataSource.class); } - @Test - public void testJdbcTemplateExists() throws Exception { - this.context.register(DataSourceAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - JdbcTemplate jdbcTemplate = this.context.getBean(JdbcTemplate.class); - assertThat(jdbcTemplate).isNotNull(); - assertThat(jdbcTemplate.getDataSource()).isNotNull(); - } - - @Test - public void testJdbcTemplateExistsWithCustomDataSource() throws Exception { - this.context.register(TestDataSourceConfiguration.class, - DataSourceAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - JdbcTemplate jdbcTemplate = this.context.getBean(JdbcTemplate.class); - assertThat(jdbcTemplate).isNotNull(); - assertThat(jdbcTemplate.getDataSource() instanceof BasicDataSource).isTrue(); - } - - @Test - public void testNamedParameterJdbcTemplateExists() throws Exception { - this.context.register(DataSourceAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - assertThat(this.context.getBean(NamedParameterJdbcOperations.class)).isNotNull(); - } - @SuppressWarnings("unchecked") private T autoConfigureDataSource(Class expectedType, final String... hiddenPackages) { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializerTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializerTests.java index d8116efffe..7d14b042f0 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializerTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializerTests.java @@ -28,7 +28,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.beans.factory.BeanCreationException; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -223,7 +223,7 @@ public class DataSourceInitializerTests { fail("User does not exist"); } catch (Exception ex) { - assertThat(ex).isInstanceOf(UnsatisfiedDependencyException.class); + assertThat(ex).isInstanceOf(BeanCreationException.class); } } @@ -245,7 +245,7 @@ public class DataSourceInitializerTests { fail("User does not exist"); } catch (Exception ex) { - assertThat(ex).isInstanceOf(UnsatisfiedDependencyException.class); + assertThat(ex).isInstanceOf(BeanCreationException.class); } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfigurationTests.java new file mode 100644 index 0000000000..eacc3da1fa --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/JdbcTemplateAutoConfigurationTests.java @@ -0,0 +1,164 @@ +/* + * Copyright 2012-2016 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 + * + * http://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.jdbc; + +import java.util.Random; + +import javax.sql.DataSource; + +import org.apache.commons.dbcp.BasicDataSource; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DataSourceAutoConfiguration}. + * + * @author Dave Syer + * @author Stephane Nicoll + * @author Kazuki Shimizu + * @since 1.4.0 + */ +public class JdbcTemplateAutoConfigurationTests { + + private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + @Before + public void init() { + EmbeddedDatabaseConnection.override = null; + EnvironmentTestUtils.addEnvironment(this.context, + "spring.datasource.initialize:false", + "spring.datasource.url:jdbc:hsqldb:mem:testdb-" + new Random().nextInt()); + } + + @After + public void restore() { + EmbeddedDatabaseConnection.override = null; + this.context.close(); + } + + @Test + public void testJdbcTemplateExists() throws Exception { + this.context.register(DataSourceAutoConfiguration.class, + JdbcTemplateAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + JdbcTemplate jdbcTemplate = this.context.getBean(JdbcTemplate.class); + assertThat(jdbcTemplate).isNotNull(); + assertThat(jdbcTemplate.getDataSource()).isNotNull(); + } + + @Test + public void testJdbcTemplateExistsWithCustomDataSource() throws Exception { + this.context.register(TestDataSourceConfiguration.class, + DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + JdbcTemplate jdbcTemplate = this.context.getBean(JdbcTemplate.class); + assertThat(jdbcTemplate).isNotNull(); + assertThat(jdbcTemplate.getDataSource() instanceof BasicDataSource).isTrue(); + } + + @Test + public void testNamedParameterJdbcTemplateExists() throws Exception { + this.context.register(DataSourceAutoConfiguration.class, + JdbcTemplateAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertThat(this.context.getBean(NamedParameterJdbcOperations.class)).isNotNull(); + } + + @Test + public void testMultiDataSource() throws Exception { + this.context.register(MultiDataSourceConfiguration.class, + DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertThat(this.context.getBeansOfType(JdbcOperations.class)).isEmpty(); + assertThat(this.context.getBeansOfType(NamedParameterJdbcOperations.class)) + .isEmpty(); + } + + @Test + public void testMultiDataSourceUsingPrimary() throws Exception { + this.context.register(MultiDataSourceUsingPrimaryConfiguration.class, + DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertThat(this.context.getBean(JdbcOperations.class)).isNotNull(); + assertThat(this.context.getBean(NamedParameterJdbcOperations.class)).isNotNull(); + } + + @Test + public void testExistingCustomJdbcTemplate() throws Exception { + this.context.register(CustomConfiguration.class, + DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertThat(this.context.getBean(JdbcOperations.class)) + .isEqualTo(this.context.getBean("customJdbcOperations")); + } + + @Test + public void testExistingCustomNamedParameterJdbcTemplate() throws Exception { + this.context.register(CustomConfiguration.class, + DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertThat(this.context.getBean(NamedParameterJdbcOperations.class)) + .isEqualTo(this.context.getBean("customNamedParameterJdbcOperations")); + } + + @Configuration + static class CustomConfiguration { + + @Bean + public JdbcOperations customJdbcOperations(DataSource dataSource) { + return new JdbcTemplate(dataSource); + } + + @Bean + public NamedParameterJdbcOperations customNamedParameterJdbcOperations( + DataSource dataSource) { + return new NamedParameterJdbcTemplate(dataSource); + } + + } + + @Configuration + static class TestDataSourceConfiguration { + + @Bean + public DataSource dataSource() { + return new TestDataSource("overridedb"); + } + + } + +}