Skip to content

Commit 8219f2b

Browse files
committed
Update DataSource auto-configuration to support XA
Update DataSource and JPA auto-configuration to consider XA datasources. See spring-projectsgh-947
1 parent 5ef1365 commit 8219f2b

12 files changed

+528
-34
lines changed

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.autoconfigure.jdbc;
1818

1919
import javax.sql.DataSource;
20+
import javax.sql.XADataSource;
2021

2122
import org.springframework.beans.factory.BeanFactoryUtils;
2223
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@@ -74,7 +75,7 @@ public static boolean containsAutoConfiguredDataSource(
7475
}
7576

7677
@Conditional(DataSourceAutoConfiguration.EmbeddedDataSourceCondition.class)
77-
@ConditionalOnMissingBean(DataSource.class)
78+
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
7879
@Import(EmbeddedDataSourceConfiguration.class)
7980
protected static class EmbeddedConfiguration {
8081

@@ -92,7 +93,7 @@ public DataSourceInitializer dataSourceInitializer() {
9293
}
9394

9495
@Conditional(DataSourceAutoConfiguration.NonEmbeddedDataSourceCondition.class)
95-
@ConditionalOnMissingBean(DataSource.class)
96+
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
9697
protected static class NonEmbeddedConfiguration {
9798

9899
@Autowired
@@ -196,7 +197,8 @@ static class DataSourceAvailableCondition extends SpringBootCondition {
196197
@Override
197198
public ConditionOutcome getMatchOutcome(ConditionContext context,
198199
AnnotatedTypeMetadata metadata) {
199-
if (hasBean(context, DataSource.class)) {
200+
if (hasBean(context, DataSource.class)
201+
|| hasBean(context, XADataSource.class)) {
200202
return ConditionOutcome
201203
.match("existing bean configured database detected");
202204
}
@@ -210,6 +212,7 @@ private boolean hasBean(ConditionContext context, Class<?> type) {
210212
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
211213
context.getBeanFactory(), type, true, false).length > 0;
212214
}
215+
213216
}
214217

215218
}

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ public class DataSourceBuilder {
4949

5050
private ClassLoader classLoader;
5151

52-
private DriverClassNameProvider driverClassNameProvider = new DriverClassNameProvider();
53-
5452
private Map<String, String> properties = new HashMap<String, String>();
5553

5654
public static DataSourceBuilder create() {
@@ -76,9 +74,9 @@ public DataSource build() {
7674
private void maybeGetDriverClassName() {
7775
if (!this.properties.containsKey("driverClassName")
7876
&& this.properties.containsKey("url")) {
79-
String cls = this.driverClassNameProvider.getDriverClassName(this.properties
80-
.get("url"));
81-
this.properties.put("driverClassName", cls);
77+
String url = this.properties.get("url");
78+
String driverClass = DatabaseDriver.fromJdbcUrl(url).getDriverClassName();
79+
this.properties.put("driverClassName", driverClass);
8280
}
8381
}
8482

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

+41-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
package org.springframework.boot.autoconfigure.jdbc;
1818

19+
import java.util.LinkedHashMap;
20+
import java.util.Map;
21+
1922
import org.springframework.beans.factory.BeanClassLoaderAware;
2023
import org.springframework.beans.factory.BeanCreationException;
2124
import org.springframework.beans.factory.InitializingBean;
@@ -64,7 +67,7 @@ public class DataSourceProperties implements BeanClassLoaderAware, InitializingB
6467

6568
private EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection.NONE;
6669

67-
private DriverClassNameProvider driverClassNameProvider = new DriverClassNameProvider();
70+
private Xa xa = new Xa();
6871

6972
@Override
7073
public void setBeanClassLoader(ClassLoader classLoader) {
@@ -86,7 +89,7 @@ protected String getDriverClassName() {
8689
String driverClassName = null;
8790

8891
if (StringUtils.hasText(this.url)) {
89-
driverClassName = this.driverClassNameProvider.getDriverClassName(this.url);
92+
driverClassName = DatabaseDriver.fromJdbcUrl(this.url).getDriverClassName();
9093
}
9194

9295
if (!StringUtils.hasText(driverClassName)) {
@@ -113,7 +116,7 @@ public String getUrl() {
113116
"Cannot determine embedded database url for database type "
114117
+ this.embeddedDatabaseConnection
115118
+ ". If you want an embedded "
116-
+ "database please put a supported on on the classpath.");
119+
+ "database please put a supported one on the classpath.");
117120
}
118121
return url;
119122
}
@@ -228,4 +231,39 @@ public ClassLoader getClassLoader() {
228231
return this.classLoader;
229232
}
230233

234+
public Xa getXa() {
235+
return this.xa;
236+
}
237+
238+
public void setXa(Xa xa) {
239+
this.xa = xa;
240+
}
241+
242+
/**
243+
* XA Specific datasource settings.
244+
*/
245+
public static class Xa {
246+
247+
private String dataSourceClassName;
248+
249+
private Map<String, String> properties = new LinkedHashMap<String, String>();
250+
251+
public String getDataSourceClassName() {
252+
return this.dataSourceClassName;
253+
}
254+
255+
public void setDataSourceClassName(String dataSourceClassName) {
256+
this.dataSourceClassName = dataSourceClassName;
257+
}
258+
259+
public Map<String, String> getProperties() {
260+
return this.properties;
261+
}
262+
263+
public void setProperties(Map<String, String> properties) {
264+
this.properties = properties;
265+
}
266+
267+
}
268+
231269
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.jdbc;
18+
19+
import org.springframework.util.Assert;
20+
import org.springframework.util.StringUtils;
21+
22+
/**
23+
* Enumeration of common database drivers.
24+
*
25+
* @author Phillip Webb
26+
* @author Maciej Walkowiak
27+
* @since 1.2.0
28+
*/
29+
enum DatabaseDriver {
30+
31+
/**
32+
* Unknown type.
33+
*/
34+
UNKNOWN(null),
35+
36+
/**
37+
* Apache Derby.
38+
*/
39+
DERBY("org.apache.derby.jdbc.EmbeddedDriver"),
40+
41+
/**
42+
* H2.
43+
*/
44+
H2("org.h2.Driver", "org.h2.jdbcx.JdbcDataSource"),
45+
46+
/**
47+
* HyperSQL DataBase.
48+
*/
49+
HSQLDB("org.hsqldb.jdbc.JDBCDriver", "org.hsqldb.jdbc.pool.JDBCXADataSource"),
50+
51+
/**
52+
* SQL Lite.
53+
*/
54+
SQLITE("org.sqlite.JDBC"),
55+
56+
/**
57+
* MySQL.
58+
*/
59+
MYSQL("com.mysql.jdbc.Driver", "org.mysql.jdbc.MySQLDataSource"),
60+
61+
/**
62+
* Maria DB.
63+
*/
64+
MARIADB("org.mariadb.jdbc.Driver", "org.mariadb.jdbc.MySQLDataSource"),
65+
66+
/**
67+
* Google App Engine.
68+
*/
69+
GOOGLE("com.google.appengine.api.rdbms.AppEngineDriver"),
70+
71+
/**
72+
* Oracle
73+
*/
74+
ORACLE("oracle.jdbc.OracleDriver", "oracle.jdbc.xa.OracleXADataSource"),
75+
76+
/**
77+
* Postres
78+
*/
79+
POSTGRESQL("org.postgresql.Driver", "org.postgresql.xa.PGXADataSource"),
80+
81+
/**
82+
* JTDS
83+
*/
84+
JTDS("net.sourceforge.jtds.jdbc.Driver"),
85+
86+
/**
87+
* SQL Server
88+
*/
89+
SQLSERVER("com.microsoft.sqlserver.jdbc.SQLServerDriver");
90+
91+
private final String driverClassName;
92+
93+
private final String xaDataSourceClassName;
94+
95+
private DatabaseDriver(String driverClassName) {
96+
this(driverClassName, null);
97+
}
98+
99+
private DatabaseDriver(String driverClassName, String xaDataSourceClassName) {
100+
this.driverClassName = driverClassName;
101+
this.xaDataSourceClassName = xaDataSourceClassName;
102+
}
103+
104+
/**
105+
* @return the driverClassName or {@code null}
106+
*/
107+
public String getDriverClassName() {
108+
return this.driverClassName;
109+
}
110+
111+
/**
112+
* @return the xaDataSourceClassName or {@code null}
113+
*/
114+
public String getXaDataSourceClassName() {
115+
return this.xaDataSourceClassName;
116+
}
117+
118+
/**
119+
* Find a {@link DatabaseDriver} for the given URL.
120+
* @param url JDBC URL
121+
* @return driver class name or {@link #UNKNOWN} if not found
122+
*/
123+
public static DatabaseDriver fromJdbcUrl(String url) {
124+
if (StringUtils.hasLength(url)) {
125+
Assert.isTrue(url.startsWith("jdbc"), "URL must start with 'jdbc'");
126+
String urlWithoutPrefix = url.substring("jdbc".length()).toLowerCase();
127+
for (DatabaseDriver driver : values()) {
128+
String prefix = ":" + driver.name().toLowerCase() + ":";
129+
if (driver != UNKNOWN && urlWithoutPrefix.startsWith(prefix)) {
130+
return driver;
131+
}
132+
}
133+
}
134+
return UNKNOWN;
135+
}
136+
137+
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
* @since 1.2.0
3737
*/
3838
@Configuration
39-
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
39+
@AutoConfigureBefore({ XADataSourceAutoConfiguration.class,
40+
DataSourceAutoConfiguration.class })
4041
@ConditionalOnClass(DataSource.class)
4142
@ConditionalOnProperty(prefix = DataSourceProperties.PREFIX, name = "jndi-name")
4243
@EnableConfigurationProperties(DataSourceProperties.class)

0 commit comments

Comments
 (0)