@ -16,10 +16,13 @@
package org.springframework.boot.autoconfigure.liquibase ;
package org.springframework.boot.autoconfigure.liquibase ;
import java.lang.reflect.Method ;
import javax.annotation.PostConstruct ;
import javax.annotation.PostConstruct ;
import javax.persistence.EntityManagerFactory ;
import javax.persistence.EntityManagerFactory ;
import javax.sql.DataSource ;
import javax.sql.DataSource ;
import liquibase.exception.LiquibaseException ;
import liquibase.integration.spring.SpringLiquibase ;
import liquibase.integration.spring.SpringLiquibase ;
import org.springframework.beans.factory.ObjectProvider ;
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.AbstractEntityManagerFactoryBean ;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean ;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean ;
import org.springframework.util.Assert ;
import org.springframework.util.Assert ;
import org.springframework.util.ReflectionUtils ;
/ * *
/ * *
* { @link EnableAutoConfiguration Auto - configuration } for Liquibase .
* { @link EnableAutoConfiguration Auto - configuration } for Liquibase .
@ -99,10 +103,9 @@ public class LiquibaseAutoConfiguration {
@Bean
@Bean
public SpringLiquibase liquibase ( ) {
public SpringLiquibase liquibase ( ) {
SpringLiquibase liquibase = new SpringLiquibase( ) ;
SpringLiquibase liquibase = create SpringLiquibase( ) ;
liquibase . setChangeLog ( this . properties . getChangeLog ( ) ) ;
liquibase . setChangeLog ( this . properties . getChangeLog ( ) ) ;
liquibase . setContexts ( this . properties . getContexts ( ) ) ;
liquibase . setContexts ( this . properties . getContexts ( ) ) ;
liquibase . setDataSource ( getDataSource ( ) ) ;
liquibase . setDefaultSchema ( this . properties . getDefaultSchema ( ) ) ;
liquibase . setDefaultSchema ( this . properties . getDefaultSchema ( ) ) ;
liquibase . setDropFirst ( this . properties . isDropFirst ( ) ) ;
liquibase . setDropFirst ( this . properties . isDropFirst ( ) ) ;
liquibase . setShouldRun ( this . properties . isEnabled ( ) ) ;
liquibase . setShouldRun ( this . properties . isEnabled ( ) ) ;
@ -112,6 +115,22 @@ public class LiquibaseAutoConfiguration {
return liquibase ;
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 ( ) {
private DataSource getDataSource ( ) {
if ( this . liquibaseDataSource ! = null ) {
if ( this . liquibaseDataSource ! = null ) {
return this . liquibaseDataSource ;
return this . liquibaseDataSource ;
@ -119,9 +138,7 @@ public class LiquibaseAutoConfiguration {
else if ( this . properties . getUrl ( ) = = null ) {
else if ( this . properties . getUrl ( ) = = null ) {
return this . dataSource ;
return this . dataSource ;
}
}
return DataSourceBuilder . create ( ) . url ( this . properties . getUrl ( ) )
return null ;
. username ( this . properties . getUser ( ) )
. password ( this . properties . getPassword ( ) ) . build ( ) ;
}
}
}
}
@ -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 ( ) ) ;
}
}
}
}
}