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 ede3c1e1936..d5d90e89def 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 @@ -131,8 +131,8 @@ public class DataSourceAutoConfiguration { * @return the class loader */ private ClassLoader getDataSourceClassLoader(ConditionContext context) { - Class dataSourceClass = new DataSourceBuilder(context.getClassLoader()) - .findType(); + Class dataSourceClass = DataSourceBuilder + .findType(context.getClassLoader()); return (dataSourceClass == null ? null : dataSourceClass.getClassLoader()); } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java index 33fac74896e..4dc8c27622c 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java @@ -180,7 +180,7 @@ public class DataSourceProperties * @return a {@link DataSourceBuilder} initialized with the customizations defined on * this instance */ - public DataSourceBuilder initializeDataSourceBuilder() { + public DataSourceBuilder initializeDataSourceBuilder() { return DataSourceBuilder.create(getClassLoader()).type(getType()) .driverClassName(determineDriverClassName()).url(determineUrl()) .username(determineUsername()).password(determinePassword()); diff --git a/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/ConfigurableDataSourceExample.java b/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/ConfigurableDataSourceExample.java index c6c24178d3b..3057cbb88e6 100644 --- a/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/ConfigurableDataSourceExample.java +++ b/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/ConfigurableDataSourceExample.java @@ -51,8 +51,8 @@ public class ConfigurableDataSourceExample { @Bean @ConfigurationProperties("app.datasource") public HikariDataSource dataSource(DataSourceProperties properties) { - return (HikariDataSource) properties.initializeDataSourceBuilder() - .type(HikariDataSource.class).build(); + return properties.initializeDataSourceBuilder().type(HikariDataSource.class) + .build(); } // end::configuration[] diff --git a/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleDataSourceExample.java b/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleDataSourceExample.java index e8139c86fbb..e52cf2bf22c 100644 --- a/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleDataSourceExample.java +++ b/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleDataSourceExample.java @@ -41,8 +41,7 @@ public class SimpleDataSourceExample { @Bean @ConfigurationProperties("app.datasource") public HikariDataSource dataSource() { - return (HikariDataSource) DataSourceBuilder.create() - .type(HikariDataSource.class).build(); + return DataSourceBuilder.create().type(HikariDataSource.class).build(); } // end::configuration[] diff --git a/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleTwoDataSourcesExample.java b/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleTwoDataSourcesExample.java index ba9f55f0cdb..1a60529776d 100644 --- a/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleTwoDataSourcesExample.java +++ b/spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleTwoDataSourcesExample.java @@ -58,8 +58,7 @@ public class SimpleTwoDataSourcesExample { @Bean @ConfigurationProperties("app.datasource.bar") public BasicDataSource barDataSource() { - return (BasicDataSource) DataSourceBuilder.create() - .type(BasicDataSource.class).build(); + return DataSourceBuilder.create().type(BasicDataSource.class).build(); } // end::configuration[] diff --git a/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java b/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java index b411959c991..3e9a74829d4 100644 --- a/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java +++ b/spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java @@ -39,11 +39,12 @@ import org.springframework.util.ClassUtils; * inject additional properties into the result you can downcast it, or use * {@code @ConfigurationProperties}. * + * @param type of DataSource produced by the builder * @author Dave Syer * @author Madhura Bhave * @since 2.0.0 */ -public class DataSourceBuilder { +public final class DataSourceBuilder { private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] { "com.zaxxer.hikari.HikariDataSource", @@ -56,24 +57,25 @@ public class DataSourceBuilder { private Map properties = new HashMap<>(); - public static DataSourceBuilder create() { - return new DataSourceBuilder(null); + public static DataSourceBuilder create() { + return new DataSourceBuilder(null); } - public static DataSourceBuilder create(ClassLoader classLoader) { - return new DataSourceBuilder(classLoader); + public static DataSourceBuilder create(ClassLoader classLoader) { + return new DataSourceBuilder(classLoader); } - public DataSourceBuilder(ClassLoader classLoader) { + private DataSourceBuilder(ClassLoader classLoader) { this.classLoader = classLoader; } - public DataSource build() { + @SuppressWarnings("unchecked") + public T build() { Class type = getType(); DataSource result = BeanUtils.instantiateClass(type); maybeGetDriverClassName(); bind(result); - return result; + return (T) result; } private void maybeGetDriverClassName() { @@ -95,40 +97,38 @@ public class DataSourceBuilder { binder.bind(ConfigurationPropertyName.EMPTY, Bindable.ofInstance(result)); } - public DataSourceBuilder type(Class type) { + @SuppressWarnings("unchecked") + public DataSourceBuilder type(Class type) { this.type = type; - return this; + return (DataSourceBuilder) this; } - public DataSourceBuilder url(String url) { + public DataSourceBuilder url(String url) { this.properties.put("url", url); return this; } - public DataSourceBuilder driverClassName(String driverClassName) { + public DataSourceBuilder driverClassName(String driverClassName) { this.properties.put("driverClassName", driverClassName); return this; } - public DataSourceBuilder username(String username) { + public DataSourceBuilder username(String username) { this.properties.put("username", username); return this; } - public DataSourceBuilder password(String password) { + public DataSourceBuilder password(String password) { this.properties.put("password", password); return this; } @SuppressWarnings("unchecked") - public Class findType() { - if (this.type != null) { - return this.type; - } + public static Class findType(ClassLoader classLoader) { for (String name : DATA_SOURCE_TYPE_NAMES) { try { return (Class) ClassUtils.forName(name, - this.classLoader); + classLoader); } catch (Exception ex) { // Swallow and continue @@ -138,7 +138,8 @@ public class DataSourceBuilder { } private Class getType() { - Class type = findType(); + Class type = this.type != null ? this.type + : findType(this.classLoader); if (type != null) { return type; } diff --git a/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java b/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java index 4a0a4d7db04..e1d2280dbe1 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java @@ -71,6 +71,13 @@ public class DataSourceBuilderTests { assertThat(this.dataSource).isInstanceOf(BasicDataSource.class); } + @Test + public void specificTypeOfDataSource() { + HikariDataSource hikariDataSource = DataSourceBuilder.create().type(HikariDataSource.class) + .build(); + assertThat(hikariDataSource).isInstanceOf(HikariDataSource.class); + } + final class HidePackagesClassLoader extends URLClassLoader { private final String[] hiddenPackages; diff --git a/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java b/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java index 473b457918e..17c6ce18459 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java @@ -86,7 +86,7 @@ public abstract class AbstractDataSourcePoolMetadataTests initializeBuilder() { return DataSourceBuilder.create().driverClassName("org.hsqldb.jdbc.JDBCDriver") .url("jdbc:hsqldb:mem:test").username("sa"); } diff --git a/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java b/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java index 99f273a4801..2cc78162776 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java @@ -90,7 +90,7 @@ public class CommonsDbcp2DataSourcePoolMetadataTests } private BasicDataSource createDataSource() { - return (BasicDataSource) initializeBuilder().type(BasicDataSource.class).build(); + return initializeBuilder().type(BasicDataSource.class).build(); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java b/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java index 19bf6512963..45921713d55 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java @@ -51,8 +51,8 @@ public class HikariDataSourcePoolMetadataTests } private HikariDataSource createDataSource(int minSize, int maxSize) { - HikariDataSource dataSource = (HikariDataSource) initializeBuilder() - .type(HikariDataSource.class).build(); + HikariDataSource dataSource = initializeBuilder().type(HikariDataSource.class) + .build(); dataSource.setMinimumIdle(minSize); dataSource.setMaximumPoolSize(maxSize); return dataSource; diff --git a/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java b/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java index 0b162c0af7b..c013556da14 100644 --- a/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java @@ -51,8 +51,7 @@ public class TomcatDataSourcePoolMetadataTests } private DataSource createDataSource(int minSize, int maxSize) { - DataSource dataSource = (DataSource) initializeBuilder().type(DataSource.class) - .build(); + DataSource dataSource = initializeBuilder().type(DataSource.class).build(); dataSource.setMinIdle(minSize); dataSource.setMaxActive(maxSize);