Skip to content

Commit bb3f32f

Browse files
committed
Add a generic to DataSourceBuilder
Closes gh-7942
1 parent 16edf72 commit bb3f32f

File tree

11 files changed

+40
-35
lines changed

11 files changed

+40
-35
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ public ConditionOutcome getMatchOutcome(ConditionContext context,
131131
* @return the class loader
132132
*/
133133
private ClassLoader getDataSourceClassLoader(ConditionContext context) {
134-
Class<?> dataSourceClass = new DataSourceBuilder(context.getClassLoader())
135-
.findType();
134+
Class<?> dataSourceClass = DataSourceBuilder
135+
.findType(context.getClassLoader());
136136
return (dataSourceClass == null ? null : dataSourceClass.getClassLoader());
137137
}
138138

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ public void afterPropertiesSet() throws Exception {
180180
* @return a {@link DataSourceBuilder} initialized with the customizations defined on
181181
* this instance
182182
*/
183-
public DataSourceBuilder initializeDataSourceBuilder() {
183+
public DataSourceBuilder<?> initializeDataSourceBuilder() {
184184
return DataSourceBuilder.create(getClassLoader()).type(getType())
185185
.driverClassName(determineDriverClassName()).url(determineUrl())
186186
.username(determineUsername()).password(determinePassword());

spring-boot-docs/src/main/java/org/springframework/boot/jdbc/ConfigurableDataSourceExample.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ public DataSourceProperties dataSourceProperties() {
5151
@Bean
5252
@ConfigurationProperties("app.datasource")
5353
public HikariDataSource dataSource(DataSourceProperties properties) {
54-
return (HikariDataSource) properties.initializeDataSourceBuilder()
55-
.type(HikariDataSource.class).build();
54+
return properties.initializeDataSourceBuilder().type(HikariDataSource.class)
55+
.build();
5656
}
5757
// end::configuration[]
5858

spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleDataSourceExample.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ static class SimpleDataSourceConfiguration {
4141
@Bean
4242
@ConfigurationProperties("app.datasource")
4343
public HikariDataSource dataSource() {
44-
return (HikariDataSource) DataSourceBuilder.create()
45-
.type(HikariDataSource.class).build();
44+
return DataSourceBuilder.create().type(HikariDataSource.class).build();
4645
}
4746
// end::configuration[]
4847

spring-boot-docs/src/main/java/org/springframework/boot/jdbc/SimpleTwoDataSourcesExample.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ public DataSource fooDataSource() {
5858
@Bean
5959
@ConfigurationProperties("app.datasource.bar")
6060
public BasicDataSource barDataSource() {
61-
return (BasicDataSource) DataSourceBuilder.create()
62-
.type(BasicDataSource.class).build();
61+
return DataSourceBuilder.create().type(BasicDataSource.class).build();
6362
}
6463
// end::configuration[]
6564

spring-boot/src/main/java/org/springframework/boot/jdbc/DataSourceBuilder.java

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@
3939
* inject additional properties into the result you can downcast it, or use
4040
* {@code @ConfigurationProperties}.
4141
*
42+
* @param <T> type of DataSource produced by the builder
4243
* @author Dave Syer
4344
* @author Madhura Bhave
4445
* @since 2.0.0
4546
*/
46-
public class DataSourceBuilder {
47+
public final class DataSourceBuilder<T extends DataSource> {
4748

4849
private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {
4950
"com.zaxxer.hikari.HikariDataSource",
@@ -56,24 +57,25 @@ public class DataSourceBuilder {
5657

5758
private Map<String, String> properties = new HashMap<>();
5859

59-
public static DataSourceBuilder create() {
60-
return new DataSourceBuilder(null);
60+
public static DataSourceBuilder<?> create() {
61+
return new DataSourceBuilder<DataSource>(null);
6162
}
6263

63-
public static DataSourceBuilder create(ClassLoader classLoader) {
64-
return new DataSourceBuilder(classLoader);
64+
public static DataSourceBuilder<?> create(ClassLoader classLoader) {
65+
return new DataSourceBuilder<DataSource>(classLoader);
6566
}
6667

67-
public DataSourceBuilder(ClassLoader classLoader) {
68+
private DataSourceBuilder(ClassLoader classLoader) {
6869
this.classLoader = classLoader;
6970
}
7071

71-
public DataSource build() {
72+
@SuppressWarnings("unchecked")
73+
public T build() {
7274
Class<? extends DataSource> type = getType();
7375
DataSource result = BeanUtils.instantiateClass(type);
7476
maybeGetDriverClassName();
7577
bind(result);
76-
return result;
78+
return (T) result;
7779
}
7880

7981
private void maybeGetDriverClassName() {
@@ -95,40 +97,38 @@ private void bind(DataSource result) {
9597
binder.bind(ConfigurationPropertyName.EMPTY, Bindable.ofInstance(result));
9698
}
9799

98-
public DataSourceBuilder type(Class<? extends DataSource> type) {
100+
@SuppressWarnings("unchecked")
101+
public <D extends DataSource> DataSourceBuilder<D> type(Class<D> type) {
99102
this.type = type;
100-
return this;
103+
return (DataSourceBuilder<D>) this;
101104
}
102105

103-
public DataSourceBuilder url(String url) {
106+
public DataSourceBuilder<T> url(String url) {
104107
this.properties.put("url", url);
105108
return this;
106109
}
107110

108-
public DataSourceBuilder driverClassName(String driverClassName) {
111+
public DataSourceBuilder<T> driverClassName(String driverClassName) {
109112
this.properties.put("driverClassName", driverClassName);
110113
return this;
111114
}
112115

113-
public DataSourceBuilder username(String username) {
116+
public DataSourceBuilder<T> username(String username) {
114117
this.properties.put("username", username);
115118
return this;
116119
}
117120

118-
public DataSourceBuilder password(String password) {
121+
public DataSourceBuilder<T> password(String password) {
119122
this.properties.put("password", password);
120123
return this;
121124
}
122125

123126
@SuppressWarnings("unchecked")
124-
public Class<? extends DataSource> findType() {
125-
if (this.type != null) {
126-
return this.type;
127-
}
127+
public static Class<? extends DataSource> findType(ClassLoader classLoader) {
128128
for (String name : DATA_SOURCE_TYPE_NAMES) {
129129
try {
130130
return (Class<? extends DataSource>) ClassUtils.forName(name,
131-
this.classLoader);
131+
classLoader);
132132
}
133133
catch (Exception ex) {
134134
// Swallow and continue
@@ -138,7 +138,8 @@ public Class<? extends DataSource> findType() {
138138
}
139139

140140
private Class<? extends DataSource> getType() {
141-
Class<? extends DataSource> type = findType();
141+
Class<? extends DataSource> type = this.type != null ? this.type
142+
: findType(this.classLoader);
142143
if (type != null) {
143144
return type;
144145
}

spring-boot/src/test/java/org/springframework/boot/jdbc/DataSourceBuilderTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ public void defaultToCommonsDbcp2AsLastResort() {
7171
assertThat(this.dataSource).isInstanceOf(BasicDataSource.class);
7272
}
7373

74+
@Test
75+
public void specificTypeOfDataSource() {
76+
HikariDataSource hikariDataSource = DataSourceBuilder.create().type(HikariDataSource.class)
77+
.build();
78+
assertThat(hikariDataSource).isInstanceOf(HikariDataSource.class);
79+
}
80+
7481
final class HidePackagesClassLoader extends URLClassLoader {
7582

7683
private final String[] hiddenPackages;

spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/AbstractDataSourcePoolMetadataTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void getPoolSizeTwoConnections() {
8686
@Test
8787
public abstract void getValidationQuery();
8888

89-
protected DataSourceBuilder initializeBuilder() {
89+
protected DataSourceBuilder<?> initializeBuilder() {
9090
return DataSourceBuilder.create().driverClassName("org.hsqldb.jdbc.JDBCDriver")
9191
.url("jdbc:hsqldb:mem:test").username("sa");
9292
}

spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/CommonsDbcp2DataSourcePoolMetadataTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private CommonsDbcp2DataSourcePoolMetadata createDataSourceMetadata(int minSize,
9090
}
9191

9292
private BasicDataSource createDataSource() {
93-
return (BasicDataSource) initializeBuilder().type(BasicDataSource.class).build();
93+
return initializeBuilder().type(BasicDataSource.class).build();
9494
}
9595

9696
}

spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/HikariDataSourcePoolMetadataTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ public void getValidationQuery() {
5151
}
5252

5353
private HikariDataSource createDataSource(int minSize, int maxSize) {
54-
HikariDataSource dataSource = (HikariDataSource) initializeBuilder()
55-
.type(HikariDataSource.class).build();
54+
HikariDataSource dataSource = initializeBuilder().type(HikariDataSource.class)
55+
.build();
5656
dataSource.setMinimumIdle(minSize);
5757
dataSource.setMaximumPoolSize(maxSize);
5858
return dataSource;

spring-boot/src/test/java/org/springframework/boot/jdbc/metadata/TomcatDataSourcePoolMetadataTests.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ public void getValidationQuery() {
5151
}
5252

5353
private DataSource createDataSource(int minSize, int maxSize) {
54-
DataSource dataSource = (DataSource) initializeBuilder().type(DataSource.class)
55-
.build();
54+
DataSource dataSource = initializeBuilder().type(DataSource.class).build();
5655
dataSource.setMinIdle(minSize);
5756
dataSource.setMaxActive(maxSize);
5857

0 commit comments

Comments
 (0)