From 8e9e502b6a07421c1f7cc081d7a78c8f8b45d14b Mon Sep 17 00:00:00 2001 From: David Liu Date: Mon, 1 Sep 2014 16:09:46 +0800 Subject: [PATCH] Add support for auto-configuration of Commons DBCP2 Closes gh-1292 Closes gh-1477 --- spring-boot-autoconfigure/pom.xml | 5 ++ .../autoconfigure/jdbc/DataSourceBuilder.java | 3 +- .../DataSourceAutoConfigurationTests.java | 70 +++++++++++++------ spring-boot-dependencies/pom.xml | 6 ++ .../main/asciidoc/spring-boot-features.adoc | 4 +- 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index 02b79097004..53947d71a5f 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -75,6 +75,11 @@ activemq-pool true + + org.apache.commons + commons-dbcp2 + true + org.apache.solr solr-solrj diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBuilder.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBuilder.java index 18d13e3f28e..65b519989ae 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBuilder.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceBuilder.java @@ -43,7 +43,8 @@ public class DataSourceBuilder { private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] { "org.apache.tomcat.jdbc.pool.DataSource", "com.zaxxer.hikari.HikariDataSource", - "org.apache.commons.dbcp.BasicDataSource" }; + "org.apache.commons.dbcp.BasicDataSource", + "org.apache.commons.dbcp2.BasicDataSource" }; private Class type; 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 8fd7c73e520..93bf7574afc 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 @@ -45,9 +45,11 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import com.zaxxer.hikari.HikariDataSource; +import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** @@ -70,8 +72,8 @@ public class DataSourceAutoConfigurationTests { @After public void restore() { EmbeddedDatabaseConnection.override = null; - if (context != null) { - context.close(); + if (this.context != null) { + this.context.close(); } } @@ -119,28 +121,26 @@ public class DataSourceAutoConfigurationTests { @Test public void testHikariIsFallback() throws Exception { - EnvironmentTestUtils.addEnvironment(this.context, - "spring.datasource.driverClassName:org.hsqldb.jdbcDriver", - "spring.datasource.url:jdbc:hsqldb:mem:testdb"); - this.context.setClassLoader(new URLClassLoader(new URL[0], getClass() - .getClassLoader()) { - @Override - protected Class loadClass(String name, boolean resolve) - throws ClassNotFoundException { - if (name.startsWith("org.apache.tomcat")) { - throw new ClassNotFoundException(); - } - return super.loadClass(name, resolve); - } - }); - this.context.register(DataSourceAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - DataSource bean = this.context.getBean(DataSource.class); - HikariDataSource pool = (HikariDataSource) bean; + HikariDataSource pool = testDataSourceFallback(HikariDataSource.class, + "org.apache.tomcat"); assertEquals("jdbc:hsqldb:mem:testdb", pool.getJdbcUrl()); } + @Test + public void commonsDbcpIsFallback() throws Exception { + BasicDataSource dataSource = testDataSourceFallback(BasicDataSource.class, + "org.apache.tomcat", "com.zaxxer.hikari"); + assertEquals("jdbc:hsqldb:mem:testdb", dataSource.getUrl()); + } + + @Test + public void commonsDbcp2IsFallback() throws Exception { + org.apache.commons.dbcp2.BasicDataSource dataSource = testDataSourceFallback( + org.apache.commons.dbcp2.BasicDataSource.class, "org.apache.tomcat", + "com.zaxxer.hikari", "org.apache.commons.dbcp."); + assertEquals("jdbc:hsqldb:mem:testdb", dataSource.getUrl()); + } + @Test public void testEmbeddedTypeDefaultsUsername() throws Exception { EnvironmentTestUtils.addEnvironment(this.context, @@ -215,6 +215,34 @@ public class DataSourceAutoConfigurationTests { assertNotNull(this.context.getBean(NamedParameterJdbcOperations.class)); } + @SuppressWarnings("unchecked") + private T testDataSourceFallback(Class expectedType, + final String... hiddenPackages) { + EnvironmentTestUtils.addEnvironment(this.context, + "spring.datasource.driverClassName:org.hsqldb.jdbcDriver", + "spring.datasource.url:jdbc:hsqldb:mem:testdb"); + this.context.setClassLoader(new URLClassLoader(new URL[0], getClass() + .getClassLoader()) { + @Override + protected Class loadClass(String name, boolean resolve) + throws ClassNotFoundException { + for (String hiddenPackage : hiddenPackages) { + if (name.startsWith(hiddenPackage)) { + throw new ClassNotFoundException(); + } + } + return super.loadClass(name, resolve); + } + }); + this.context.register(DataSourceAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + DataSource bean = this.context.getBean(DataSource.class); + + assertThat(bean, instanceOf(expectedType)); + return (T) bean; + } + @Configuration static class TestDataSourceConfiguration { diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index d89b6165b2d..e794ecb3c27 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -54,6 +54,7 @@ 1.9.2 3.2.1 1.4 + 2.0.1 2.1 1.6 2.2 @@ -484,6 +485,11 @@ commons-collections ${commons-collections.version} + + org.apache.commons + commons-dbcp2 + ${commons-dbcp2.version} + commons-dbcp commons-dbcp diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 8766524241c..db1f067fc02 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -1249,7 +1249,9 @@ Production database connections can also be auto-configured using a pooling * We prefer the Tomcat pooling `DataSource` for its performance and concurrency, so if that is available we always choose it. -* If commons-dbcp is available we will use that, but we don't recommend it in production. +* If HikariCP is available we will use it +* If Commons DBCP is available we will use it, but we don't recommend it in production. +* Lastly, if Commons DBCP2 is available we will use it If you use the `spring-boot-starter-jdbc` or `spring-boot-starter-data-jpa` ``starter POMs'' you will automcatically get a dependency to `tomcat-jdbc`.