11/*
2- * Copyright 2012-2020 the original author or authors.
2+ * Copyright 2012-2023 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2424import oracle .jdbc .OracleConnection ;
2525import oracle .ucp .jdbc .PoolDataSourceImpl ;
2626
27+ import org .springframework .beans .factory .ObjectProvider ;
28+ import org .springframework .boot .autoconfigure .condition .ConditionalOnBean ;
2729import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
2830import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
2931import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
3032import org .springframework .boot .context .properties .ConfigurationProperties ;
33+ import org .springframework .boot .jdbc .DataSourceBuilder ;
3134import org .springframework .boot .jdbc .DatabaseDriver ;
3235import org .springframework .context .annotation .Bean ;
3336import org .springframework .context .annotation .Configuration ;
4043 * @author Phillip Webb
4144 * @author Stephane Nicoll
4245 * @author Fabio Grassi
46+ * @author Moritz Halbritter
47+ * @author Andy Wilkinson
4348 */
4449abstract class DataSourceConfiguration {
4550
@@ -48,6 +53,17 @@ protected static <T> T createDataSource(DataSourceProperties properties, Class<?
4853 return (T ) properties .initializeDataSourceBuilder ().type (type ).build ();
4954 }
5055
56+ @ SuppressWarnings ("unchecked" )
57+ protected static <T > T createDataSource (JdbcConnectionDetails connectionDetails , Class <? extends DataSource > type ,
58+ ClassLoader classLoader ) {
59+ return (T ) DataSourceBuilder .create (classLoader )
60+ .url (connectionDetails .getJdbcUrl ())
61+ .username (connectionDetails .getUsername ())
62+ .password (connectionDetails .getPassword ())
63+ .type (type )
64+ .build ();
65+ }
66+
5167 /**
5268 * Tomcat Pool DataSource configuration.
5369 */
@@ -58,13 +74,26 @@ protected static <T> T createDataSource(DataSourceProperties properties, Class<?
5874 matchIfMissing = true )
5975 static class Tomcat {
6076
77+ @ Bean
78+ @ ConditionalOnBean (JdbcConnectionDetails .class )
79+ static TomcatJdbcConnectionDetailsBeanPostProcessor tomcatJdbcConnectionDetailsBeanPostProcessor (
80+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) {
81+ return new TomcatJdbcConnectionDetailsBeanPostProcessor (connectionDetailsProvider );
82+ }
83+
6184 @ Bean
6285 @ ConfigurationProperties (prefix = "spring.datasource.tomcat" )
63- org .apache .tomcat .jdbc .pool .DataSource dataSource (DataSourceProperties properties ) {
64- org .apache .tomcat .jdbc .pool .DataSource dataSource = createDataSource (properties ,
65- org .apache .tomcat .jdbc .pool .DataSource .class );
66- DatabaseDriver databaseDriver = DatabaseDriver .fromJdbcUrl (properties .determineUrl ());
67- String validationQuery = databaseDriver .getValidationQuery ();
86+ org .apache .tomcat .jdbc .pool .DataSource dataSource (DataSourceProperties properties ,
87+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) {
88+ JdbcConnectionDetails connectionDetails = connectionDetailsProvider .getIfAvailable ();
89+ Class <? extends DataSource > dataSourceType = org .apache .tomcat .jdbc .pool .DataSource .class ;
90+ org .apache .tomcat .jdbc .pool .DataSource dataSource = (connectionDetails != null )
91+ ? createDataSource (connectionDetails , dataSourceType , properties .getClassLoader ())
92+ : createDataSource (properties , dataSourceType );
93+ String validationQuery ;
94+ String url = (connectionDetails != null ) ? connectionDetails .getJdbcUrl () : properties .determineUrl ();
95+ DatabaseDriver databaseDriver = DatabaseDriver .fromJdbcUrl (url );
96+ validationQuery = databaseDriver .getValidationQuery ();
6897 if (validationQuery != null ) {
6998 dataSource .setTestOnBorrow (true );
7099 dataSource .setValidationQuery (validationQuery );
@@ -84,10 +113,21 @@ org.apache.tomcat.jdbc.pool.DataSource dataSource(DataSourceProperties propertie
84113 matchIfMissing = true )
85114 static class Hikari {
86115
116+ @ Bean
117+ @ ConditionalOnBean (JdbcConnectionDetails .class )
118+ static HikariJdbcConnectionDetailsBeanPostProcessor jdbcConnectionDetailsHikariBeanPostProcessor (
119+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) {
120+ return new HikariJdbcConnectionDetailsBeanPostProcessor (connectionDetailsProvider );
121+ }
122+
87123 @ Bean
88124 @ ConfigurationProperties (prefix = "spring.datasource.hikari" )
89- HikariDataSource dataSource (DataSourceProperties properties ) {
90- HikariDataSource dataSource = createDataSource (properties , HikariDataSource .class );
125+ HikariDataSource dataSource (DataSourceProperties properties ,
126+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) {
127+ JdbcConnectionDetails connectionDetails = connectionDetailsProvider .getIfAvailable ();
128+ HikariDataSource dataSource = (connectionDetails != null )
129+ ? createDataSource (connectionDetails , HikariDataSource .class , properties .getClassLoader ())
130+ : createDataSource (properties , HikariDataSource .class );
91131 if (StringUtils .hasText (properties .getName ())) {
92132 dataSource .setPoolName (properties .getName ());
93133 }
@@ -106,10 +146,22 @@ HikariDataSource dataSource(DataSourceProperties properties) {
106146 matchIfMissing = true )
107147 static class Dbcp2 {
108148
149+ @ Bean
150+ @ ConditionalOnBean (JdbcConnectionDetails .class )
151+ static Dbcp2JdbcConnectionDetailsBeanPostProcessor dbcp2JdbcConnectionDetailsBeanPostProcessor (
152+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) {
153+ return new Dbcp2JdbcConnectionDetailsBeanPostProcessor (connectionDetailsProvider );
154+ }
155+
109156 @ Bean
110157 @ ConfigurationProperties (prefix = "spring.datasource.dbcp2" )
111- org .apache .commons .dbcp2 .BasicDataSource dataSource (DataSourceProperties properties ) {
112- return createDataSource (properties , org .apache .commons .dbcp2 .BasicDataSource .class );
158+ org .apache .commons .dbcp2 .BasicDataSource dataSource (DataSourceProperties properties ,
159+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) {
160+ JdbcConnectionDetails connectionDetails = connectionDetailsProvider .getIfAvailable ();
161+ Class <? extends DataSource > dataSourceType = org .apache .commons .dbcp2 .BasicDataSource .class ;
162+ return (connectionDetails != null )
163+ ? createDataSource (connectionDetails , dataSourceType , properties .getClassLoader ())
164+ : createDataSource (properties , dataSourceType );
113165 }
114166
115167 }
@@ -124,10 +176,21 @@ org.apache.commons.dbcp2.BasicDataSource dataSource(DataSourceProperties propert
124176 matchIfMissing = true )
125177 static class OracleUcp {
126178
179+ @ Bean
180+ @ ConditionalOnBean (JdbcConnectionDetails .class )
181+ static OracleUcpJdbcConnectionDetailsBeanPostProcessor oracleUcpJdbcConnectionDetailsBeanPostProcessor (
182+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) {
183+ return new OracleUcpJdbcConnectionDetailsBeanPostProcessor (connectionDetailsProvider );
184+ }
185+
127186 @ Bean
128187 @ ConfigurationProperties (prefix = "spring.datasource.oracleucp" )
129- PoolDataSourceImpl dataSource (DataSourceProperties properties ) throws SQLException {
130- PoolDataSourceImpl dataSource = createDataSource (properties , PoolDataSourceImpl .class );
188+ PoolDataSourceImpl dataSource (DataSourceProperties properties ,
189+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) throws SQLException {
190+ JdbcConnectionDetails connectionDetails = connectionDetailsProvider .getIfAvailable ();
191+ PoolDataSourceImpl dataSource = (connectionDetails != null )
192+ ? createDataSource (connectionDetails , PoolDataSourceImpl .class , properties .getClassLoader ())
193+ : createDataSource (properties , PoolDataSourceImpl .class );
131194 dataSource .setValidateConnectionOnBorrow (true );
132195 if (StringUtils .hasText (properties .getName ())) {
133196 dataSource .setConnectionPoolName (properties .getName ());
@@ -146,7 +209,17 @@ PoolDataSourceImpl dataSource(DataSourceProperties properties) throws SQLExcepti
146209 static class Generic {
147210
148211 @ Bean
149- DataSource dataSource (DataSourceProperties properties ) {
212+ DataSource dataSource (DataSourceProperties properties ,
213+ ObjectProvider <JdbcConnectionDetails > connectionDetailsProvider ) {
214+ JdbcConnectionDetails connectionDetails = connectionDetailsProvider .getIfAvailable ();
215+ if (connectionDetails != null ) {
216+ return DataSourceBuilder .create (properties .getClassLoader ())
217+ .url (connectionDetails .getJdbcUrl ())
218+ .username (connectionDetails .getUsername ())
219+ .password (connectionDetails .getPassword ())
220+ .type (properties .getType ())
221+ .build ();
222+ }
150223 return properties .initializeDataSourceBuilder ().build ();
151224 }
152225
0 commit comments