diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java index ca9c1e2bcd..29a635bfbe 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java @@ -16,10 +16,13 @@ package org.springframework.boot.autoconfigure.liquibase; +import java.lang.reflect.Method; + import javax.annotation.PostConstruct; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; +import liquibase.exception.LiquibaseException; import liquibase.integration.spring.SpringLiquibase; import org.springframework.beans.factory.ObjectProvider; @@ -42,6 +45,7 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.util.Assert; +import org.springframework.util.ReflectionUtils; /** * {@link EnableAutoConfiguration Auto-configuration} for Liquibase. @@ -98,10 +102,9 @@ public class LiquibaseAutoConfiguration { @Bean public SpringLiquibase liquibase() { - SpringLiquibase liquibase = new SpringLiquibase(); + SpringLiquibase liquibase = createSpringLiquibase(); liquibase.setChangeLog(this.properties.getChangeLog()); liquibase.setContexts(this.properties.getContexts()); - liquibase.setDataSource(getDataSource()); liquibase.setDefaultSchema(this.properties.getDefaultSchema()); liquibase.setDropFirst(this.properties.isDropFirst()); liquibase.setShouldRun(this.properties.isEnabled()); @@ -111,6 +114,22 @@ public class LiquibaseAutoConfiguration { return liquibase; } + private SpringLiquibase createSpringLiquibase() { + SpringLiquibase liquibase; + DataSource dataSource = getDataSource(); + if (dataSource == null) { + dataSource = DataSourceBuilder.create().url(this.properties.getUrl()) + .username(this.properties.getUser()) + .password(this.properties.getPassword()).build(); + liquibase = new DataSourceClosingSpringLiquibase(); + } + else { + liquibase = new SpringLiquibase(); + } + liquibase.setDataSource(dataSource); + return liquibase; + } + private DataSource getDataSource() { if (this.liquibaseDataSource != null) { return this.liquibaseDataSource; @@ -118,9 +137,7 @@ public class LiquibaseAutoConfiguration { else if (this.properties.getUrl() == null) { return this.dataSource; } - return DataSourceBuilder.create().url(this.properties.getUrl()) - .username(this.properties.getUser()) - .password(this.properties.getPassword()).build(); + return null; } } @@ -141,4 +158,26 @@ public class LiquibaseAutoConfiguration { } + /** + * A custom {@link SpringLiquibase} extension that close the underlying + * {@link DataSource} once the database has been migrated. + */ + private static final class DataSourceClosingSpringLiquibase extends SpringLiquibase { + + @Override + public void afterPropertiesSet() throws LiquibaseException { + super.afterPropertiesSet(); + closeDataSource(); + } + + private void closeDataSource() { + Method closeMethod = ReflectionUtils.findMethod(getDataSource().getClass(), + "close"); + if (closeMethod != null) { + ReflectionUtils.invokeMethod(closeMethod, getDataSource()); + } + } + + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java index c98d09ce07..bd3785708f 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java @@ -186,7 +186,9 @@ public class LiquibaseAutoConfigurationTests { PropertyPlaceholderAutoConfiguration.class); this.context.refresh(); SpringLiquibase liquibase = this.context.getBean(SpringLiquibase.class); - assertThat(liquibase.getDataSource().getConnection().getMetaData().getURL()) + DataSource dataSource = liquibase.getDataSource(); + assertThat(ReflectionTestUtils.getField(dataSource, "pool")).isNull(); + assertThat(dataSource.getConnection().getMetaData().getURL()) .isEqualTo("jdbc:hsqldb:mem:liquibase"); }