1616
1717package org .springframework .boot .autoconfigure .liquibase ;
1818
19+ import java .lang .reflect .Method ;
20+
1921import javax .annotation .PostConstruct ;
2022import javax .persistence .EntityManagerFactory ;
2123import javax .sql .DataSource ;
2224
25+ import liquibase .exception .LiquibaseException ;
2326import liquibase .integration .spring .SpringLiquibase ;
2427
2528import org .springframework .beans .factory .ObjectProvider ;
4245import org .springframework .orm .jpa .AbstractEntityManagerFactoryBean ;
4346import org .springframework .orm .jpa .LocalContainerEntityManagerFactoryBean ;
4447import org .springframework .util .Assert ;
48+ import org .springframework .util .ReflectionUtils ;
4549
4650/**
4751 * {@link EnableAutoConfiguration Auto-configuration} for Liquibase.
@@ -98,10 +102,9 @@ public void checkChangelogExists() {
98102
99103 @ Bean
100104 public SpringLiquibase liquibase () {
101- SpringLiquibase liquibase = new SpringLiquibase ();
105+ SpringLiquibase liquibase = createSpringLiquibase ();
102106 liquibase .setChangeLog (this .properties .getChangeLog ());
103107 liquibase .setContexts (this .properties .getContexts ());
104- liquibase .setDataSource (getDataSource ());
105108 liquibase .setDefaultSchema (this .properties .getDefaultSchema ());
106109 liquibase .setDropFirst (this .properties .isDropFirst ());
107110 liquibase .setShouldRun (this .properties .isEnabled ());
@@ -111,16 +114,30 @@ public SpringLiquibase liquibase() {
111114 return liquibase ;
112115 }
113116
117+ private SpringLiquibase createSpringLiquibase () {
118+ SpringLiquibase liquibase ;
119+ DataSource dataSource = getDataSource ();
120+ if (dataSource == null ) {
121+ dataSource = DataSourceBuilder .create ().url (this .properties .getUrl ())
122+ .username (this .properties .getUser ())
123+ .password (this .properties .getPassword ()).build ();
124+ liquibase = new DataSourceClosingSpringLiquibase ();
125+ }
126+ else {
127+ liquibase = new SpringLiquibase ();
128+ }
129+ liquibase .setDataSource (dataSource );
130+ return liquibase ;
131+ }
132+
114133 private DataSource getDataSource () {
115134 if (this .liquibaseDataSource != null ) {
116135 return this .liquibaseDataSource ;
117136 }
118137 else if (this .properties .getUrl () == null ) {
119138 return this .dataSource ;
120139 }
121- return DataSourceBuilder .create ().url (this .properties .getUrl ())
122- .username (this .properties .getUser ())
123- .password (this .properties .getPassword ()).build ();
140+ return null ;
124141 }
125142
126143 }
@@ -141,4 +158,26 @@ public LiquibaseJpaDependencyConfiguration() {
141158
142159 }
143160
161+ /**
162+ * A custom {@link SpringLiquibase} extension that close the underlying
163+ * {@link DataSource} once the database has been migrated.
164+ */
165+ private static final class DataSourceClosingSpringLiquibase extends SpringLiquibase {
166+
167+ @ Override
168+ public void afterPropertiesSet () throws LiquibaseException {
169+ super .afterPropertiesSet ();
170+ closeDataSource ();
171+ }
172+
173+ private void closeDataSource () {
174+ Method closeMethod = ReflectionUtils .findMethod (getDataSource ().getClass (),
175+ "close" );
176+ if (closeMethod != null ) {
177+ ReflectionUtils .invokeMethod (closeMethod , getDataSource ());
178+ }
179+ }
180+
181+ }
182+
144183}
0 commit comments