diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.java index 9feb54adf81..075eca8d3ef 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabase.java @@ -15,7 +15,6 @@ */ package org.springframework.jdbc.datasource.embedded; -import javax.annotation.PreDestroy; import javax.sql.DataSource; /** @@ -29,6 +28,5 @@ public interface EmbeddedDatabase extends DataSource { /** * Shutdown this embedded database. */ - @PreDestroy void shutdown(); } diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java index 481591df3fc..4f616c470d2 100644 --- a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactory.java @@ -55,7 +55,7 @@ public class EmbeddedDatabaseFactory { private DatabasePopulator databasePopulator; - private EmbeddedDatabase database; + private DataSource dataSource; /** * Creates a default {@link EmbeddedDatabaseFactory}. @@ -122,42 +122,51 @@ public class EmbeddedDatabaseFactory { * Factory method that returns the embedded database instance. */ public EmbeddedDatabase getDatabase() { - if (database == null) { - initDatabase(); + if (dataSource == null) { + initDataSource(); } - return database; + return new EmbeddedDataSourceProxy(dataSource); } - - // internal helper methods - private void initDatabase() { + // subclassing hooks + + protected void initDataSource() { // create the embedded database source first - database = new EmbeddedDataSourceProxy(createDataSource()); if (logger.isInfoEnabled()) { logger.info("Created embedded database '" + databaseName + "'"); } + databaseConfigurer.configureConnectionProperties(dataSourceFactory.getConnectionProperties(), databaseName); + dataSource = dataSourceFactory.getDataSource(); if (databasePopulator != null) { // now populate the database populateDatabase(); } } - private DataSource createDataSource() { - databaseConfigurer.configureConnectionProperties(dataSourceFactory.getConnectionProperties(), databaseName); - return dataSourceFactory.getDataSource(); + protected DataSource getDataSource() { + return dataSource; } + + protected void shutdownDataSource() { + if (dataSource != null) { + databaseConfigurer.shutdown(dataSource); + dataSource = null; + } + } + + // internal helper methods private void populateDatabase() { - TransactionTemplate template = new TransactionTemplate(new DataSourceTransactionManager(database)); + TransactionTemplate template = new TransactionTemplate(new DataSourceTransactionManager(dataSource)); template.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { - databasePopulator.populate(new JdbcTemplate(database)); + databasePopulator.populate(new JdbcTemplate(dataSource)); } }); } - class EmbeddedDataSourceProxy implements EmbeddedDatabase { + private class EmbeddedDataSourceProxy implements EmbeddedDatabase { private DataSource dataSource; public EmbeddedDataSourceProxy(DataSource dataSource) { @@ -198,16 +207,9 @@ public class EmbeddedDatabaseFactory { } public void shutdown() { - shutdownDatabase(); + shutdownDataSource(); } } - private void shutdownDatabase() { - if (database != null) { - databaseConfigurer.shutdown(database); - database = null; - } - } - } \ No newline at end of file diff --git a/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBean.java b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBean.java new file mode 100644 index 00000000000..e6682fe2385 --- /dev/null +++ b/org.springframework.jdbc/src/main/java/org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseFactoryBean.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002-2009 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.jdbc.datasource.embedded; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; + +/** + * A subclass of {@link EmbeddedDatabaseFactory} that implements {@link FactoryBean} for registration as a Spring bean. + * Returns the actual {@link DataSource} that provides connectivity to the embedded database to Spring. + * The target DataSource is returned instead of a {@link EmbeddedDatabase} proxy since the FactoryBean will manage the initialization and destruction lifecycle of the database instance. + * Implements DisposableBean to shutdown the embedded database when the managing Spring container is shutdown. + * + * @author Keith Donald + */ +public class EmbeddedDatabaseFactoryBean extends EmbeddedDatabaseFactory implements FactoryBean, InitializingBean, DisposableBean { + + public void afterPropertiesSet() throws Exception { + initDataSource(); + } + + public DataSource getObject() throws Exception { + return getDataSource(); + } + + public Class getObjectType() { + return DataSource.class; + } + + public boolean isSingleton() { + return true; + } + + public void destroy() throws Exception { + shutdownDataSource(); + } + +}