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 46abc3f268..7570d9a47b 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. @@ -99,10 +103,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()); @@ -112,6 +115,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; @@ -119,9 +138,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; } } @@ -142,4 +159,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 c9a3f58c19..c71d0ea5c1 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2017 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. @@ -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"); }