diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/AbstractDataSourceConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/AbstractDataSourceConfiguration.java index 98a22d0519..6e8f829ab9 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/AbstractDataSourceConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/AbstractDataSourceConfiguration.java @@ -25,7 +25,7 @@ import org.springframework.util.StringUtils; /** * Base class for configuration of a database pool. - * + * * @author Dave Syer */ @ConfigurationProperties(name = DataSourceAutoConfiguration.CONFIGURATION_PREFIX) @@ -55,6 +55,12 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader private boolean testOnReturn = false; + private boolean testWhileIdle = false; + + private int timeBetweenEvictionRunsMillis = getDefaultTimeBetweenEvictionRunsMillis(); + + private int minEvictableIdleTimeMillis = getDefaultMinEvictableIdleTimeMillis(); + private ClassLoader classLoader; private EmbeddedDatabaseConnection embeddedDatabaseConnection = EmbeddedDatabaseConnection.NONE; @@ -164,6 +170,18 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader this.testOnReturn = testOnReturn; } + public void setTestWhileIdle(boolean testWhileIdle) { + this.testWhileIdle = testWhileIdle; + } + + public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) { + this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; + } + + public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) { + this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; + } + public int getInitialSize() { return this.initialSize; } @@ -192,4 +210,16 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader return this.testOnReturn; } + protected boolean isTestWhileIdle() { + return this.testWhileIdle; + } + + protected int getTimeBetweenEvictionRunsMillis() { return this.timeBetweenEvictionRunsMillis; } + + protected int getMinEvictableIdleTimeMillis() { return this.minEvictableIdleTimeMillis; } + + protected abstract int getDefaultTimeBetweenEvictionRunsMillis(); + + protected abstract int getDefaultMinEvictableIdleTimeMillis(); + } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfiguration.java index 67e30682cd..5e0745d493 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfiguration.java @@ -24,6 +24,7 @@ import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.commons.pool.impl.GenericObjectPool; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.dao.DataAccessResourceFailureException; @@ -31,7 +32,7 @@ import org.springframework.dao.DataAccessResourceFailureException; /** * Configuration for a Commons DBCP database pool. The DBCP pool is popular but not * recommended in high volume environments (the Tomcat DataSource is more reliable). - * + * * @author Dave Syer * @see DataSourceAutoConfiguration */ @@ -66,7 +67,11 @@ public class CommonsDataSourceConfiguration extends AbstractDataSourceConfigurat this.pool.setMinIdle(getMinIdle()); this.pool.setTestOnBorrow(isTestOnBorrow()); this.pool.setTestOnReturn(isTestOnReturn()); + this.pool.setTestWhileIdle(isTestWhileIdle()); + this.pool.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis()); + this.pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis()); this.pool.setValidationQuery(getValidationQuery()); + return this.pool; } @@ -75,12 +80,20 @@ public class CommonsDataSourceConfiguration extends AbstractDataSourceConfigurat if (this.pool != null) { try { this.pool.close(); - } - catch (SQLException ex) { + } catch (SQLException ex) { throw new DataAccessResourceFailureException( "Could not close data source", ex); } } } + @Override + protected int getDefaultTimeBetweenEvictionRunsMillis() { + return (int) GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS; + } + + @Override + protected int getDefaultMinEvictableIdleTimeMillis() { + return (int) GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS; + } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfiguration.java index 0f084258d4..5c4d66a638 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfiguration.java @@ -25,7 +25,7 @@ import org.springframework.context.annotation.Configuration; /** * Configuration for a Tomcat database pool. The Tomcat pool provides superior performance * and tends not to deadlock in high volume environments. - * + * * @author Dave Syer * @see DataSourceAutoConfiguration */ @@ -51,6 +51,9 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati this.pool.setMinIdle(getMinIdle()); this.pool.setTestOnBorrow(isTestOnBorrow()); this.pool.setTestOnReturn(isTestOnReturn()); + this.pool.setTestWhileIdle(isTestWhileIdle()); + this.pool.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis()); + this.pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis()); this.pool.setValidationQuery(getValidationQuery()); return this.pool; } @@ -62,4 +65,13 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati } } + @Override + protected int getDefaultTimeBetweenEvictionRunsMillis() { + return 5000; + } + + @Override + protected int getDefaultMinEvictableIdleTimeMillis() { + return 60000; + } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfigurationTests.java index 358c76342d..f7c7ee2fd5 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/CommonsDataSourceConfigurationTests.java @@ -18,14 +18,18 @@ package org.springframework.boot.autoconfigure.jdbc; import javax.sql.DataSource; +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.pool.impl.GenericObjectPool; import org.junit.Test; +import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** * Tests for {@link CommonsDataSourceConfiguration}. - * + * * @author Dave Syer */ public class CommonsDataSourceConfigurationTests { @@ -40,4 +44,32 @@ public class CommonsDataSourceConfigurationTests { this.context.close(); } + @Test + public void testDataSourcePropertiesOverridden() throws Exception { + this.context.register(CommonsDataSourceConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.url:jdbc:foo//bar/spam"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testWhileIdle:true"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testOnBorrow:true"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testOnReturn:true"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.timeBetweenEvictionRunsMillis:10000"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.minEvictableIdleTimeMillis:12345"); + this.context.refresh(); + BasicDataSource ds = this.context.getBean(BasicDataSource.class); + assertEquals("jdbc:foo//bar/spam", ds.getUrl()); + assertEquals(true, ds.getTestWhileIdle()); + assertEquals(true, ds.getTestOnBorrow()); + assertEquals(true, ds.getTestOnReturn()); + assertEquals(10000, ds.getTimeBetweenEvictionRunsMillis()); + assertEquals(12345, ds.getMinEvictableIdleTimeMillis()); + } + + @Test + public void testDataSourceDefaultsPreserved() throws Exception { + this.context.register(CommonsDataSourceConfiguration.class); + this.context.refresh(); + BasicDataSource ds = this.context.getBean(BasicDataSource.class); + assertEquals(GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS, ds.getTimeBetweenEvictionRunsMillis()); + assertEquals(GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS, ds.getMinEvictableIdleTimeMillis()); + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java index d79f285fe8..4c36852015 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jdbc/TomcatDataSourceConfigurationTests.java @@ -33,7 +33,7 @@ import static org.junit.Assert.assertNotNull; /** * Tests for {@link TomcatDataSourceConfiguration}. - * + * * @author Dave Syer */ public class TomcatDataSourceConfigurationTests { @@ -56,12 +56,29 @@ public class TomcatDataSourceConfigurationTests { @Test public void testDataSourcePropertiesOverridden() throws Exception { this.context.register(TomcatDataSourceConfiguration.class); - EnvironmentTestUtils.addEnvironment(this.context, - "spring.datasource.url:jdbc:foo//bar/spam"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.url:jdbc:foo//bar/spam"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testWhileIdle:true"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testOnBorrow:true"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.testOnReturn:true"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.timeBetweenEvictionRunsMillis:10000"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.minEvictableIdleTimeMillis:12345"); + this.context.refresh(); + org.apache.tomcat.jdbc.pool.DataSource ds = this.context.getBean(org.apache.tomcat.jdbc.pool.DataSource.class); + assertEquals("jdbc:foo//bar/spam", ds.getUrl()); + assertEquals(true, ds.isTestWhileIdle()); + assertEquals(true, ds.isTestOnBorrow()); + assertEquals(true, ds.isTestOnReturn()); + assertEquals(10000, ds.getTimeBetweenEvictionRunsMillis()); + assertEquals(12345, ds.getMinEvictableIdleTimeMillis()); + } + + @Test + public void testDataSourceDefaultsPreserved() throws Exception { + this.context.register(TomcatDataSourceConfiguration.class); this.context.refresh(); - assertEquals("jdbc:foo//bar/spam", - this.context.getBean(org.apache.tomcat.jdbc.pool.DataSource.class) - .getUrl()); + org.apache.tomcat.jdbc.pool.DataSource ds = this.context.getBean(org.apache.tomcat.jdbc.pool.DataSource.class); + assertEquals(5000, ds.getTimeBetweenEvictionRunsMillis()); + assertEquals(60000, ds.getMinEvictableIdleTimeMillis()); } @Test(expected = BeanCreationException.class)