From a12f0dcd12e7c3931d6df17b249fdb1b030d25c5 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 17 May 2013 17:48:08 +0100 Subject: [PATCH] [bs-51] Add support for h2 and Derby embedded database Also included support for database shutdown in @PreDestroy [Fixes #48387903] --- .../jdbc/BasicDataSourceConfiguration.java | 29 +++++++++++++---- .../jdbc/EmbeddedDatabaseConfiguration.java | 31 +++++++++++++++---- .../jdbc/TomcatDataSourceConfiguration.java | 22 +++++++++---- 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceConfiguration.java index 1516ac81b6..bd38bbcc9d 100644 --- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceConfiguration.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/BasicDataSourceConfiguration.java @@ -15,6 +15,9 @@ */ package org.springframework.bootstrap.autoconfigure.jdbc; +import java.sql.SQLException; + +import javax.annotation.PreDestroy; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; @@ -22,6 +25,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.dao.DataAccessResourceFailureException; /** * Configuration for a Commons DBCP database pool. The DBCP pool is popular but not @@ -34,16 +38,29 @@ import org.springframework.context.annotation.Configuration; public class BasicDataSourceConfiguration extends AbstractDataSourceConfiguration { private static Log logger = LogFactory.getLog(BasicDataSourceConfiguration.class); + private BasicDataSource pool; @Bean public DataSource dataSource() { logger.info("Hint: using Commons DBCP BasicDataSource. It's going to work, but the Tomcat DataSource is more reliable."); - BasicDataSource pool = new BasicDataSource(); - pool.setDriverClassName(getDriverClassName()); - pool.setUrl(getUrl()); - pool.setUsername(getUsername()); - pool.setPassword(getPassword()); - return pool; + this.pool = new BasicDataSource(); + this.pool.setDriverClassName(getDriverClassName()); + this.pool.setUrl(getUrl()); + this.pool.setUsername(getUsername()); + this.pool.setPassword(getPassword()); + return this.pool; + } + + @PreDestroy + public void close() { + if (this.pool != null) { + try { + this.pool.close(); + } catch (SQLException e) { + throw new DataAccessResourceFailureException( + "Could not close data source", e); + } + } } } diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java index a4998a6f2e..fce5f3a590 100644 --- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/EmbeddedDatabaseConfiguration.java @@ -19,11 +19,13 @@ package org.springframework.bootstrap.autoconfigure.jdbc; import java.util.LinkedHashMap; import java.util.Map; +import javax.annotation.PreDestroy; import javax.sql.DataSource; import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; import org.springframework.util.ClassUtils; @@ -36,25 +38,42 @@ import org.springframework.util.ClassUtils; @Configuration public class EmbeddedDatabaseConfiguration { - private static final Map EMBEDDED_DATABASE_TYPE_CLASSES; private static final Map EMBEDDED_DATABASE_DRIVER_CLASSES; private static final Map EMBEDDED_DATABASE_URLS; + + private EmbeddedDatabase database; + static { - EMBEDDED_DATABASE_TYPE_CLASSES = new LinkedHashMap(); - EMBEDDED_DATABASE_TYPE_CLASSES.put(EmbeddedDatabaseType.HSQL, - "org.hsqldb.Database"); + EMBEDDED_DATABASE_DRIVER_CLASSES = new LinkedHashMap(); + EMBEDDED_DATABASE_DRIVER_CLASSES.put(EmbeddedDatabaseType.H2, "org.h2.Driver"); + EMBEDDED_DATABASE_DRIVER_CLASSES.put(EmbeddedDatabaseType.DERBY, + "org.apache.derby.jdbc.EmbeddedDriver"); EMBEDDED_DATABASE_DRIVER_CLASSES.put(EmbeddedDatabaseType.HSQL, "org.hsqldb.jdbcDriver"); + EMBEDDED_DATABASE_URLS = new LinkedHashMap(); + EMBEDDED_DATABASE_URLS.put(EmbeddedDatabaseType.H2, + "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1"); + EMBEDDED_DATABASE_URLS.put(EmbeddedDatabaseType.DERBY, + "jdbc:derby:memory:testdb;create=true"); EMBEDDED_DATABASE_URLS.put(EmbeddedDatabaseType.HSQL, "jdbc:hsqldb:mem:testdb"); + } @Bean public DataSource dataSource() { EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder() .setType(getEmbeddedDatabaseType()); - return builder.build(); + this.database = builder.build(); + return this.database; + } + + @PreDestroy + public void close() { + if (this.database != null) { + this.database.shutdown(); + } } public static String getEmbeddedDatabaseDriverClass( @@ -67,7 +86,7 @@ public class EmbeddedDatabaseConfiguration { } public static EmbeddedDatabaseType getEmbeddedDatabaseType() { - for (Map.Entry entry : EMBEDDED_DATABASE_TYPE_CLASSES + for (Map.Entry entry : EMBEDDED_DATABASE_DRIVER_CLASSES .entrySet()) { if (ClassUtils.isPresent(entry.getValue(), EmbeddedDatabaseConfiguration.class.getClassLoader())) { diff --git a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceConfiguration.java b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceConfiguration.java index 344a810812..3b6cfd09bf 100644 --- a/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceConfiguration.java +++ b/spring-bootstrap/src/main/java/org/springframework/bootstrap/autoconfigure/jdbc/TomcatDataSourceConfiguration.java @@ -15,6 +15,7 @@ */ package org.springframework.bootstrap.autoconfigure.jdbc; +import javax.annotation.PreDestroy; import javax.sql.DataSource; import org.springframework.context.annotation.Bean; @@ -30,14 +31,23 @@ import org.springframework.context.annotation.Configuration; @Configuration public class TomcatDataSourceConfiguration extends AbstractDataSourceConfiguration { + private org.apache.tomcat.jdbc.pool.DataSource pool; + @Bean public DataSource dataSource() { - org.apache.tomcat.jdbc.pool.DataSource pool = new org.apache.tomcat.jdbc.pool.DataSource(); - pool.setDriverClassName(getDriverClassName()); - pool.setUrl(getUrl()); - pool.setUsername(getUsername()); - pool.setPassword(getPassword()); - return pool; + this.pool = new org.apache.tomcat.jdbc.pool.DataSource(); + this.pool.setDriverClassName(getDriverClassName()); + this.pool.setUrl(getUrl()); + this.pool.setUsername(getUsername()); + this.pool.setPassword(getPassword()); + return this.pool; + } + + @PreDestroy + public void close() { + if (this.pool != null) { + this.pool.close(); + } } }