diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java index 8ee68d3e1c..160097dc0d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration.java @@ -36,11 +36,13 @@ import org.flywaydb.core.api.configuration.FluentConfiguration; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.data.jpa.EntityManagerFactoryDependsOnPostProcessor; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayDataSourceCondition; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.autoconfigure.jdbc.JdbcOperationsDependsOnPostProcessor; @@ -52,6 +54,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.GenericConverter; @@ -82,7 +85,7 @@ import org.springframework.util.StringUtils; @SuppressWarnings("deprecation") @Configuration(proxyBeanMethods = false) @ConditionalOnClass(Flyway.class) -@ConditionalOnBean(DataSource.class) +@Conditional(FlywayDataSourceCondition.class) @ConditionalOnProperty(prefix = "spring.flyway", name = "enabled", matchIfMissing = true) @AutoConfigureAfter({ DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) @@ -462,4 +465,23 @@ public class FlywayAutoConfiguration { } + static final class FlywayDataSourceCondition extends AnyNestedCondition { + + FlywayDataSourceCondition() { + super(ConfigurationPhase.REGISTER_BEAN); + } + + @ConditionalOnBean(DataSource.class) + private static final class DataSourceBeanCondition { + + } + + @ConditionalOnProperty(prefix = "spring.flyway", name = "url", + matchIfMissing = false) + private static final class FlywayUrlCondition { + + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java index 23127c3ede..d97c566cd3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java @@ -28,6 +28,7 @@ import liquibase.integration.spring.SpringLiquibase; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -37,10 +38,12 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.autoconfigure.jdbc.JdbcOperationsDependsOnPostProcessor; import org.springframework.boot.autoconfigure.jdbc.NamedParameterJdbcOperationsDependsOnPostProcessor; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseDataSourceCondition; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.io.Resource; @@ -65,9 +68,9 @@ import org.springframework.util.Assert; */ @Configuration(proxyBeanMethods = false) @ConditionalOnClass({ SpringLiquibase.class, DatabaseChange.class }) -@ConditionalOnBean(DataSource.class) @ConditionalOnProperty(prefix = "spring.liquibase", name = "enabled", matchIfMissing = true) +@Conditional(LiquibaseDataSourceCondition.class) @AutoConfigureAfter({ DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) public class LiquibaseAutoConfiguration { @@ -225,4 +228,23 @@ public class LiquibaseAutoConfiguration { } + static final class LiquibaseDataSourceCondition extends AnyNestedCondition { + + LiquibaseDataSourceCondition() { + super(ConfigurationPhase.REGISTER_BEAN); + } + + @ConditionalOnBean(DataSource.class) + private static final class DataSourceBeanCondition { + + } + + @ConditionalOnProperty(prefix = "spring.liquibase", name = "url", + matchIfMissing = false) + private static final class LiquibaseUrlCondition { + + } + + } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java index 374484c975..2140ee6cdc 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/flyway/FlywayAutoConfigurationTests.java @@ -79,11 +79,22 @@ public class FlywayAutoConfigurationTests { .withPropertyValues("spring.datasource.generate-unique-name=true"); @Test - public void noDataSource() { + public void backsOffWithNoDataSourceBeanAndNoFlywayUrl() { this.contextRunner .run((context) -> assertThat(context).doesNotHaveBean(Flyway.class)); } + @Test + public void createsDataSourceWithNoDataSourceBeanAndFlywayUrl() { + this.contextRunner + .withPropertyValues( + "spring.flyway.url:jdbc:hsqldb:mem:" + UUID.randomUUID()) + .run((context) -> { + assertThat(context).hasSingleBean(Flyway.class); + assertThat(context.getBean(Flyway.class).getDataSource()).isNotNull(); + }); + } + @Test public void createDataSourceWithUrl() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java index 86c264c30a..3619b25c9e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfigurationTests.java @@ -78,11 +78,23 @@ public class LiquibaseAutoConfigurationTests { .withPropertyValues("spring.datasource.generate-unique-name=true"); @Test - public void noDataSource() { + public void backsOffWithNoDataSourceBeanAndNoLiquibaseUrl() { this.contextRunner.run( (context) -> assertThat(context).doesNotHaveBean(SpringLiquibase.class)); } + @Test + public void createsDataSourceWithNoDataSourceBeanAndLiquibaseUrl() { + this.contextRunner + .withPropertyValues("spring.liquibase.url:jdbc:hsqldb:mem:liquibase") + .run(assertLiquibase((liquibase) -> { + DataSource dataSource = liquibase.getDataSource(); + assertThat(((HikariDataSource) dataSource).isClosed()).isTrue(); + assertThat(((HikariDataSource) dataSource).getJdbcUrl()) + .isEqualTo("jdbc:hsqldb:mem:liquibase"); + })); + } + @Test public void defaultSpringLiquibase() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class)