This commit is contained in:
Phillip Webb
2014-03-14 16:17:08 -07:00
parent bb3ea39d80
commit 80ac1fb0cd
50 changed files with 469 additions and 366 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,12 +46,12 @@ public abstract class SpringBootCondition implements Condition {
recordEvaluation(context, classOrMethodName, outcome);
return outcome.isMatch();
}
catch (NoClassDefFoundError e) {
catch (NoClassDefFoundError ex) {
throw new IllegalStateException(
"Could not evaluate condition owing to internal class not found. "
+ "This can happen if you are @ComponentScanning a springframework package "
+ "(e.g. if you put a @ComponentScan in the default package by mistake)",
e);
+ "This can happen if you are @ComponentScanning a "
+ "springframework package (e.g. if you put a @ComponentScan "
+ "in the default package by mistake)", ex);
}
}

View File

@@ -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)
@@ -51,17 +51,17 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader
private String validationQuery;
private boolean testOnBorrow = false;
private boolean testOnBorrow;
private boolean testOnReturn = false;
private boolean testOnReturn;
private boolean testWhileIdle = false;
private boolean testWhileIdle;
private int timeBetweenEvictionRunsMillis = getDefaultTimeBetweenEvictionRunsMillis();
private Integer timeBetweenEvictionRunsMillis;
private int minEvictableIdleTimeMillis = getDefaultMinEvictableIdleTimeMillis();
private Integer minEvictableIdleTimeMillis;
private int maxWaitMillis = getDefaultMaxWaitMillis();
private Integer maxWaitMillis;
private ClassLoader classLoader;
@@ -184,7 +184,9 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public void setMaxWait(int maxWaitMillis) { this.maxWaitMillis = maxWaitMillis; }
public void setMaxWait(int maxWaitMillis) {
this.maxWaitMillis = maxWaitMillis;
}
public int getInitialSize() {
return this.initialSize;
@@ -218,15 +220,16 @@ public abstract class AbstractDataSourceConfiguration implements BeanClassLoader
return this.testWhileIdle;
}
protected int getTimeBetweenEvictionRunsMillis() { return this.timeBetweenEvictionRunsMillis; }
protected Integer getTimeBetweenEvictionRunsMillis() {
return this.timeBetweenEvictionRunsMillis;
}
protected int getMinEvictableIdleTimeMillis() { return this.minEvictableIdleTimeMillis; }
protected Integer getMinEvictableIdleTimeMillis() {
return this.minEvictableIdleTimeMillis;
}
protected int getMaxWaitMillis() { return this.maxWaitMillis; }
protected Integer getMaxWaitMillis() {
return this.maxWaitMillis;
}
protected abstract int getDefaultTimeBetweenEvictionRunsMillis();
protected abstract int getDefaultMinEvictableIdleTimeMillis();
protected abstract int getDefaultMaxWaitMillis();
}

View File

@@ -24,7 +24,6 @@ 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;
@@ -32,7 +31,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
*/
@@ -52,27 +51,38 @@ public class CommonsDataSourceConfiguration extends AbstractDataSourceConfigurat
public DataSource dataSource() {
logger.info("Hint: using Commons DBCP BasicDataSource. It's going to work, "
+ "but the Tomcat DataSource is more reliable.");
this.pool = new BasicDataSource();
this.pool.setDriverClassName(getDriverClassName());
this.pool.setUrl(getUrl());
this.pool = createAndSetupPool();
return this.pool;
}
private BasicDataSource createAndSetupPool() {
BasicDataSource pool = new BasicDataSource();
pool.setDriverClassName(getDriverClassName());
pool.setUrl(getUrl());
if (getUsername() != null) {
this.pool.setUsername(getUsername());
pool.setUsername(getUsername());
}
if (getPassword() != null) {
this.pool.setPassword(getPassword());
pool.setPassword(getPassword());
}
this.pool.setInitialSize(getInitialSize());
this.pool.setMaxActive(getMaxActive());
this.pool.setMaxIdle(getMaxIdle());
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());
this.pool.setMaxWait(getMaxWaitMillis());
return this.pool;
pool.setInitialSize(getInitialSize());
pool.setMaxActive(getMaxActive());
pool.setMaxIdle(getMaxIdle());
pool.setMinIdle(getMinIdle());
pool.setTestOnBorrow(isTestOnBorrow());
pool.setTestOnReturn(isTestOnReturn());
pool.setTestWhileIdle(isTestWhileIdle());
pool.setValidationQuery(getValidationQuery());
if (getTimeBetweenEvictionRunsMillis() != null) {
pool.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
}
if (getMinEvictableIdleTimeMillis() != null) {
pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
}
if (getMaxWaitMillis() != null) {
pool.setMaxWait(getMaxWaitMillis());
}
return pool;
}
@PreDestroy
@@ -80,25 +90,12 @@ 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;
}
@Override
protected int getDefaultMaxWaitMillis() {
return (int) GenericObjectPool.DEFAULT_MAX_WAIT;
}
}

View File

@@ -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
*/
@@ -54,12 +54,19 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati
this.pool.setTestOnBorrow(isTestOnBorrow());
this.pool.setTestOnReturn(isTestOnReturn());
this.pool.setTestWhileIdle(isTestWhileIdle());
this.pool.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
this.pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
if (getTimeBetweenEvictionRunsMillis() != null) {
this.pool
.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
}
if (getMinEvictableIdleTimeMillis() != null) {
this.pool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
}
this.pool.setValidationQuery(getValidationQuery());
this.pool.setValidationInterval(this.validationInterval);
this.pool.setMaxWait(getMaxWaitMillis());
if (jdbcInterceptors != null) {
if (getMaxWaitMillis() != null) {
this.pool.setMaxWait(getMaxWaitMillis());
}
if (this.jdbcInterceptors != null) {
this.pool.setJdbcInterceptors(this.jdbcInterceptors);
}
return this.pool;
@@ -72,22 +79,11 @@ public class TomcatDataSourceConfiguration extends AbstractDataSourceConfigurati
}
}
@Override
protected int getDefaultTimeBetweenEvictionRunsMillis() {
return 5000;
public void setJdbcInterceptors(String jdbcInterceptors) {
this.jdbcInterceptors = jdbcInterceptors;
}
@Override
protected int getDefaultMinEvictableIdleTimeMillis() {
return 60000;
public void setValidationInterval(long validationInterval) {
this.validationInterval = validationInterval;
}
@Override
protected int getDefaultMaxWaitMillis() {
return 30000;
}
public void setJdbcInterceptors(String jdbcInterceptors) { this.jdbcInterceptors = jdbcInterceptors; }
public void setValidationInterval(long validationInterval) { this.validationInterval = validationInterval; }
}

View File

@@ -84,11 +84,9 @@ public class ThymeleafAutoConfiguration {
if (checkTemplateLocation) {
Resource resource = this.resourceLoader.getResource(this.environment
.getProperty("prefix", DEFAULT_PREFIX));
Assert.state(
resource.exists(),
"Cannot find template location: "
+ resource
+ " (please add some templates or check your Thymeleaf configuration)");
Assert.state(resource.exists(), "Cannot find template location: "
+ resource + " (please add some templates "
+ "or check your Thymeleaf configuration)");
}
}

View File

@@ -101,15 +101,11 @@ public class DispatcherServletAutoConfiguration {
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
ConditionOutcome outcome = checkServlets(beanFactory);
if (!outcome.isMatch()) {
return outcome;
}
return checkServletRegistrations(beanFactory);
}
@@ -123,9 +119,9 @@ public class DispatcherServletAutoConfiguration {
.containsBean(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
if (servlets.isEmpty()) {
if (containsDispatcherBean) {
return ConditionOutcome
.noMatch("found no DispatcherServlet but a non-DispatcherServlet named "
+ DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
return ConditionOutcome.noMatch("found no DispatcherServlet "
+ "but a non-DispatcherServlet named "
+ DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
}
return ConditionOutcome.match("no DispatcherServlet found");
}
@@ -138,9 +134,8 @@ public class DispatcherServletAutoConfiguration {
+ DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
}
return ConditionOutcome
.match("one or more DispatcherServlets found and none is named "
+ DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
return ConditionOutcome.match("one or more DispatcherServlets "
+ "found and none is named " + DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
}
@@ -154,9 +149,9 @@ public class DispatcherServletAutoConfiguration {
if (registrations.isEmpty()) {
if (containsDispatcherRegistrationBean) {
return ConditionOutcome
.noMatch("found no ServletRegistrationBean but a non-ServletRegistrationBean named "
+ DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
return ConditionOutcome.noMatch("found no ServletRegistrationBean "
+ "but a non-ServletRegistrationBean named "
+ DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
}
return ConditionOutcome.match("no ServletRegistrationBean found");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,11 +29,13 @@ import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link CommonsDataSourceConfiguration}.
*
*
* @author Dave Syer
*/
public class CommonsDataSourceConfigurationTests {
private static final String PREFIX = "spring.datasource.";
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@Test
@@ -47,13 +49,16 @@ public class CommonsDataSourceConfigurationTests {
@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");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.maxWait:1234");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX
+ "url:jdbc:foo//bar/spam");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX + "testWhileIdle:true");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX + "testOnBorrow:true");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX + "testOnReturn:true");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX
+ "timeBetweenEvictionRunsMillis:10000");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX
+ "minEvictableIdleTimeMillis:12345");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX + "maxWait:1234");
this.context.refresh();
BasicDataSource ds = this.context.getBean(BasicDataSource.class);
assertEquals("jdbc:foo//bar/spam", ds.getUrl());
@@ -70,8 +75,10 @@ public class CommonsDataSourceConfigurationTests {
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());
assertEquals(GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
ds.getTimeBetweenEvictionRunsMillis());
assertEquals(GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS,
ds.getMinEvictableIdleTimeMillis());
assertEquals(GenericObjectPool.DEFAULT_MAX_WAIT, ds.getMaxWait());
}

View File

@@ -37,11 +37,13 @@ import static org.junit.Assert.fail;
/**
* Tests for {@link TomcatDataSourceConfiguration}.
*
*
* @author Dave Syer
*/
public class TomcatDataSourceConfigurationTests {
private static final String PREFIX = "spring.datasource.";
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@After
@@ -60,17 +62,23 @@ 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.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");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.maxWait:1234");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.jdbcInterceptors:SlowQueryReport");
EnvironmentTestUtils.addEnvironment(this.context, "spring.datasource.validationInterval:9999");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX
+ "url:jdbc:foo//bar/spam");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX + "testWhileIdle:true");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX + "testOnBorrow:true");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX + "testOnReturn:true");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX
+ "timeBetweenEvictionRunsMillis:10000");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX
+ "minEvictableIdleTimeMillis:12345");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX + "maxWait:1234");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX
+ "jdbcInterceptors:SlowQueryReport");
EnvironmentTestUtils.addEnvironment(this.context, PREFIX
+ "validationInterval:9999");
this.context.refresh();
org.apache.tomcat.jdbc.pool.DataSource ds = this.context.getBean(org.apache.tomcat.jdbc.pool.DataSource.class);
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());
@@ -82,8 +90,10 @@ public class TomcatDataSourceConfigurationTests {
assertDataSourceHasInterceptors(ds);
}
private void assertDataSourceHasInterceptors(DataSourceProxy ds) throws ClassNotFoundException {
PoolProperties.InterceptorDefinition[] interceptors = ds.getJdbcInterceptorsAsArray();
private void assertDataSourceHasInterceptors(DataSourceProxy ds)
throws ClassNotFoundException {
PoolProperties.InterceptorDefinition[] interceptors = ds
.getJdbcInterceptorsAsArray();
for (PoolProperties.InterceptorDefinition interceptor : interceptors) {
if (SlowQueryReport.class == interceptor.getInterceptorClass()) {
return;
@@ -96,7 +106,8 @@ public class TomcatDataSourceConfigurationTests {
public void testDataSourceDefaultsPreserved() throws Exception {
this.context.register(TomcatDataSourceConfiguration.class);
this.context.refresh();
org.apache.tomcat.jdbc.pool.DataSource ds = this.context.getBean(org.apache.tomcat.jdbc.pool.DataSource.class);
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());
assertEquals(30000, ds.getMaxWait());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2013 the original author or authors.
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletCont
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
@@ -76,7 +76,7 @@ public class ServerPropertiesTests {
public void testCustomizeTomcat() throws Exception {
ConfigurableEmbeddedServletContainer factory = mock(ConfigurableEmbeddedServletContainer.class);
this.properties.customize(factory);
verify(factory, times(0)).setContextPath("");
verify(factory, never()).setContextPath("");
}
@Test