diff --git a/spring-boot-devtools/pom.xml b/spring-boot-devtools/pom.xml
index 495f1e3f52b..30b67cc4eaa 100644
--- a/spring-boot-devtools/pom.xml
+++ b/spring-boot-devtools/pom.xml
@@ -39,6 +39,11 @@
log4j-core
true
+
+ org.springframework
+ spring-jdbc
+ true
+
org.springframework
spring-web
@@ -71,6 +76,11 @@
true
+
+ com.h2database
+ h2
+ test
+
org.springframework
spring-webmvc
@@ -92,6 +102,10 @@
${jetty.version}
test
+
+ org.postgresql
+ postgresql
+
org.springframework.boot
spring-boot-starter-thymeleaf
diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java
new file mode 100644
index 00000000000..549e6e14dee
--- /dev/null
+++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfiguration.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2012-2016 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.devtools.autoconfigure;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for DevTools-specific
+ * {@link DataSource} configuration.
+ *
+ * @author Andy Wilkinson
+ * @since 1.3.3
+ */
+@AutoConfigureAfter(DataSourceAutoConfiguration.class)
+@ConditionalOnBean({ DataSource.class, DataSourceProperties.class })
+@Configuration
+public class DevToolsDataSourceAutoConfiguration {
+
+ @Bean
+ NonEmbeddedInMemoryDatabaseShutdownExecutor inMemoryDatabaseShutdownExecutor(
+ DataSource dataSource, DataSourceProperties dataSourceProperties) {
+ return new NonEmbeddedInMemoryDatabaseShutdownExecutor(dataSource,
+ dataSourceProperties);
+ }
+
+ static final class NonEmbeddedInMemoryDatabaseShutdownExecutor
+ implements DisposableBean {
+
+ private static final Set IN_MEMORY_DRIVER_CLASS_NAMES = new HashSet(
+ Arrays.asList("org.apache.derby.jdbc.EmbeddedDriver", "org.h2.Driver",
+ "org.h2.jdbcx.JdbcDataSource", "org.hsqldb.jdbcDriver",
+ "org.hsqldb.jdbc.JDBCDriver",
+ "org.hsqldb.jdbc.pool.JDBCXADataSource"));
+
+ private final DataSource dataSource;
+
+ private final DataSourceProperties dataSourceProperties;
+
+ public NonEmbeddedInMemoryDatabaseShutdownExecutor(DataSource dataSource,
+ DataSourceProperties dataSourceProperties) {
+ this.dataSource = dataSource;
+ this.dataSourceProperties = dataSourceProperties;
+ }
+
+ @Override
+ public void destroy() throws Exception {
+ if (dataSourceRequiresShutdown()) {
+ this.dataSource.getConnection().createStatement().execute("SHUTDOWN");
+ }
+ }
+
+ private boolean dataSourceRequiresShutdown() {
+ return IN_MEMORY_DRIVER_CLASS_NAMES
+ .contains(this.dataSourceProperties.getDriverClassName())
+ && (!(this.dataSource instanceof EmbeddedDatabase));
+ }
+
+ }
+
+}
diff --git a/spring-boot-devtools/src/main/resources/META-INF/spring.factories b/spring-boot-devtools/src/main/resources/META-INF/spring.factories
index fc66a3dcdb6..6afcc572994 100644
--- a/spring-boot-devtools/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-devtools/src/main/resources/META-INF/spring.factories
@@ -8,6 +8,7 @@ org.springframework.boot.devtools.restart.RestartApplicationListener
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration,\
org.springframework.boot.devtools.autoconfigure.LocalDevToolsAutoConfiguration,\
org.springframework.boot.devtools.autoconfigure.RemoteDevToolsAutoConfiguration
diff --git a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfigurationTests.java b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfigurationTests.java
new file mode 100644
index 00000000000..57c5a340d48
--- /dev/null
+++ b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/autoconfigure/DevToolsDataSourceAutoConfigurationTests.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2012-2016 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.boot.devtools.autoconfigure;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.DataSource;
+
+import org.junit.Test;
+
+import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.test.EnvironmentTestUtils;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
+
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Tests for {@link DevToolsDataSourceAutoConfiguration}.
+ *
+ * @author Andy Wilkinson
+ */
+public class DevToolsDataSourceAutoConfigurationTests {
+
+ @Test
+ public void embeddedDatabaseIsNotShutDown() throws SQLException {
+ ConfigurableApplicationContext context = createContext("org.h2.Driver",
+ EmbeddedDatabaseConfiguration.class);
+ DataSource dataSource = context.getBean(DataSource.class);
+ context.close();
+ verify(dataSource, times(0)).getConnection();
+ }
+
+ @Test
+ public void externalDatabaseIsNotShutDown() throws SQLException {
+ ConfigurableApplicationContext context = createContext("org.postgresql.Driver",
+ DataSourceConfiguration.class);
+ DataSource dataSource = context.getBean(DataSource.class);
+ context.close();
+ verify(dataSource, times(0)).getConnection();
+ }
+
+ @Test
+ public void nonEmbeddedInMemoryDatabaseIsShutDown() throws SQLException {
+ ConfigurableApplicationContext context = createContext("org.h2.Driver",
+ DataSourceConfiguration.class);
+ DataSource dataSource = context.getBean(DataSource.class);
+ Connection connection = mock(Connection.class);
+ given(dataSource.getConnection()).willReturn(connection);
+ Statement statement = mock(Statement.class);
+ given(connection.createStatement()).willReturn(statement);
+ context.close();
+ verify(statement).execute("SHUTDOWN");
+ }
+
+ private ConfigurableApplicationContext createContext(String driver,
+ Class>... classes) {
+ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
+ context.register(classes);
+ context.register(DevToolsDataSourceAutoConfiguration.class);
+ EnvironmentTestUtils.addEnvironment(context,
+ "spring.datasource.driver-class-name:" + driver);
+ context.refresh();
+ return context;
+ }
+
+ @Configuration
+ @EnableConfigurationProperties(DataSourceProperties.class)
+ static class EmbeddedDatabaseConfiguration {
+
+ @Bean
+ public EmbeddedDatabase embeddedDatabase() {
+ return mock(EmbeddedDatabase.class);
+ }
+ }
+
+ @Configuration
+ @EnableConfigurationProperties(DataSourceProperties.class)
+ static class DataSourceConfiguration {
+
+ @Bean
+ public DataSource in() {
+ return mock(DataSource.class);
+ }
+
+ }
+
+}