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 f9d6c26be2..62d071c615 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 @@ -34,6 +34,7 @@ import org.flywaydb.core.api.MigrationVersion; import org.flywaydb.core.api.callback.Callback; import org.flywaydb.core.api.configuration.FluentConfiguration; import org.flywaydb.core.api.migration.JavaMigration; +import org.jooq.DSLContext; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -44,6 +45,7 @@ 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.flyway.FlywayAutoConfiguration.FlywayDataSourceCondition; +import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayDslContextDependsOnPostProcessor; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayEntityManagerFactoryDependsOnPostProcessor; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayJdbcOperationsDependsOnPostProcessor; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayNamedParameterJdbcOperationsDependencyConfiguration; @@ -52,7 +54,11 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.autoconfigure.jdbc.JdbcOperationsDependsOnPostProcessor; import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.NamedParameterJdbcOperationsDependsOnPostProcessor; +<<<<<<< HEAD import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor; +======= +import org.springframework.boot.autoconfigure.jooq.DslContextDependsOnPostProcessor; +>>>>>>> 2.4.x import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -97,7 +103,7 @@ import org.springframework.util.StringUtils; @AutoConfigureAfter({ DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) @Import({ FlywayEntityManagerFactoryDependsOnPostProcessor.class, FlywayJdbcOperationsDependsOnPostProcessor.class, - FlywayNamedParameterJdbcOperationsDependencyConfiguration.class }) + FlywayNamedParameterJdbcOperationsDependencyConfiguration.class, FlywayDslContextDependsOnPostProcessor.class }) public class FlywayAutoConfiguration { @Bean @@ -116,7 +122,8 @@ public class FlywayAutoConfiguration { @EnableConfigurationProperties({ DataSourceProperties.class, FlywayProperties.class }) @Import({ FlywayMigrationInitializerEntityManagerFactoryDependsOnPostProcessor.class, FlywayMigrationInitializerJdbcOperationsDependsOnPostProcessor.class, - FlywayMigrationInitializerNamedParameterJdbcOperationsDependsOnPostProcessor.class }) + FlywayMigrationInitializerNamedParameterJdbcOperationsDependsOnPostProcessor.class, + FlywayMigrationInitializerDslContextDependsOnPostProcessor.class }) public static class FlywayConfiguration { @Bean @@ -357,6 +364,20 @@ public class FlywayAutoConfiguration { } + /** + * Post processor to ensure that {@link DSLContext} beans depend on any + * {@link FlywayMigrationInitializer} beans. + */ + @ConditionalOnClass(DSLContext.class) + @ConditionalOnBean(DSLContext.class) + static class FlywayMigrationInitializerDslContextDependsOnPostProcessor extends DslContextDependsOnPostProcessor { + + FlywayMigrationInitializerDslContextDependsOnPostProcessor() { + super(FlywayMigrationInitializer.class); + } + + } + /** * Post processor to ensure that {@link EntityManagerFactory} beans depend on any * {@link Flyway} beans. @@ -400,6 +421,20 @@ public class FlywayAutoConfiguration { } + /** + * Post processor to ensure that {@link DSLContext} beans depend on any {@link Flyway} + * beans. + */ + @ConditionalOnClass(DSLContext.class) + @ConditionalOnBean(DSLContext.class) + protected static class FlywayDslContextDependsOnPostProcessor extends DslContextDependsOnPostProcessor { + + public FlywayDslContextDependsOnPostProcessor() { + super(Flyway.class); + } + + } + private static class LocationResolver { private static final String VENDOR_PLACEHOLDER = "{vendor}"; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DslContextDependsOnPostProcessor.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DslContextDependsOnPostProcessor.java new file mode 100644 index 0000000000..d951fba610 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/DslContextDependsOnPostProcessor.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2021 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jooq; + +import org.jooq.DSLContext; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor; + +/** + * {@link BeanFactoryPostProcessor} that can be used to dynamically declare that all + * {@link DSLContext} beans should "depend on" one or more specific beans. + * + * @author EddĂș MelĂ©ndez + * @since 2.3.9 + * @see BeanDefinition#setDependsOn(String[]) + */ +public class DslContextDependsOnPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor { + + /** + * Creates a new {@code DslContextDependsOnPostProcessor} that will set up + * dependencies upon beans with the given names. + * @param dependsOn names of the beans to depend upon + */ + public DslContextDependsOnPostProcessor(String... dependsOn) { + super(DSLContext.class, dependsOn); + } + + /** + * Creates a new {@code DslContextDependsOnPostProcessor} that will set up + * dependencies upon beans with the given types. + * @param dependsOn types of the beans to depend upon + */ + public DslContextDependsOnPostProcessor(Class... dependsOn) { + super(DSLContext.class, dependsOn); + } + +} 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 c78217f3b0..fbaeeaa207 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 @@ -23,6 +23,7 @@ import javax.sql.DataSource; import liquibase.change.DatabaseChange; import liquibase.integration.spring.SpringLiquibase; +import org.jooq.DSLContext; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -36,7 +37,9 @@ 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.jooq.DslContextDependsOnPostProcessor; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseDataSourceCondition; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseDslContextDependsOnPostProcessor; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseEntityManagerFactoryDependsOnPostProcessor; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseJdbcOperationsDependsOnPostProcessor; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration.LiquibaseNamedParameterJdbcOperationsDependsOnPostProcessor; @@ -78,7 +81,8 @@ import org.springframework.util.StringUtils; @AutoConfigureAfter({ DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) @Import({ LiquibaseEntityManagerFactoryDependsOnPostProcessor.class, LiquibaseJdbcOperationsDependsOnPostProcessor.class, - LiquibaseNamedParameterJdbcOperationsDependsOnPostProcessor.class }) + LiquibaseNamedParameterJdbcOperationsDependsOnPostProcessor.class, + LiquibaseDslContextDependsOnPostProcessor.class }) public class LiquibaseAutoConfiguration { @Bean @@ -172,8 +176,8 @@ public class LiquibaseAutoConfiguration { } /** - * Post processor to ensure that {@link EntityManagerFactory} beans depend on the - * liquibase bean. + * Post processor to ensure that {@link EntityManagerFactory} beans depend on any + * {@link SpringLiquibase} beans. */ @ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class) @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) @@ -187,8 +191,8 @@ public class LiquibaseAutoConfiguration { } /** - * Additional configuration to ensure that {@link JdbcOperations} beans depend on the - * liquibase bean. + * Additional configuration to ensure that {@link JdbcOperations} beans depend on any + * {@link SpringLiquibase} beans. */ @ConditionalOnClass(JdbcOperations.class) @ConditionalOnBean(JdbcOperations.class) @@ -202,7 +206,7 @@ public class LiquibaseAutoConfiguration { /** * Post processor to ensure that {@link NamedParameterJdbcOperations} beans depend on - * the liquibase bean. + * any {@link SpringLiquibase} beans. */ @ConditionalOnClass(NamedParameterJdbcOperations.class) @ConditionalOnBean(NamedParameterJdbcOperations.class) @@ -215,6 +219,20 @@ public class LiquibaseAutoConfiguration { } + /** + * Post processor to ensure that {@link DSLContext} beans depend on any + * {@link SpringLiquibase} beans. + */ + @ConditionalOnClass(DSLContext.class) + @ConditionalOnBean(DSLContext.class) + static class LiquibaseDslContextDependsOnPostProcessor extends DslContextDependsOnPostProcessor { + + LiquibaseDslContextDependsOnPostProcessor() { + super(SpringLiquibase.class); + } + + } + static final class LiquibaseDataSourceCondition extends AnyNestedCondition { LiquibaseDataSourceCondition() { 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 e9a58f9336..9e60ef80bf 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2021 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. @@ -32,11 +32,15 @@ import org.flywaydb.core.api.callback.Event; import org.flywaydb.core.api.migration.JavaMigration; import org.flywaydb.core.internal.license.FlywayTeamsUpgradeRequiredException; import org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.jooq.impl.DefaultDSLContext; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InOrder; import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.jdbc.DataSourceBuilder; @@ -585,6 +589,33 @@ class FlywayAutoConfigurationTests { }); } + @Test + void whenFlywayIsAutoConfiguredThenJooqDslContextDependsOnFlywayBeans() { + this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, JooqConfiguration.class) + .run((context) -> { + BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("dslContext"); + assertThat(beanDefinition.getDependsOn()).containsExactly("flywayInitializer", "flyway"); + }); + } + + @Test + void whenCustomMigrationInitializerIsDefinedThenJooqDslContextDependsOnIt() { + this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, JooqConfiguration.class, + CustomFlywayMigrationInitializer.class).run((context) -> { + BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("dslContext"); + assertThat(beanDefinition.getDependsOn()).containsExactly("flywayMigrationInitializer", "flyway"); + }); + } + + @Test + void whenCustomFlywayIsDefinedThenJooqDslContextDependsOnIt() { + this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, JooqConfiguration.class, + CustomFlyway.class).run((context) -> { + BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("dslContext"); + assertThat(beanDefinition.getDependsOn()).containsExactly("customFlyway"); + }); + } + @Configuration(proxyBeanMethods = false) static class FlywayDataSourceConfiguration { @@ -661,6 +692,16 @@ class FlywayAutoConfigurationTests { } + @Configuration(proxyBeanMethods = false) + static class CustomFlyway { + + @Bean + Flyway customFlyway() { + return Flyway.configure().load(); + } + + } + @Configuration(proxyBeanMethods = false) static class CustomFlywayMigrationInitializerWithJpaConfiguration { @@ -812,6 +853,16 @@ class FlywayAutoConfigurationTests { } + @Configuration(proxyBeanMethods = false) + static class JooqConfiguration { + + @Bean + DSLContext dslContext() { + return new DefaultDSLContext(SQLDialect.H2); + } + + } + static final class CustomClassLoader extends ClassLoader { private CustomClassLoader(ClassLoader parent) { 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 f2945e518d..bd349ce9fd 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 @@ -37,6 +37,7 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration; import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; +import org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; @@ -370,6 +371,25 @@ class LiquibaseAutoConfigurationTests { .run(assertLiquibase((liquibase) -> assertThat(liquibase.getTag()).isEqualTo("1.0.0"))); } + @Test + void whenLiquibaseIsAutoConfiguredThenJooqDslContextDependsOnSpringLiquibaseBeans() { + this.contextRunner.withConfiguration(AutoConfigurations.of(JooqAutoConfiguration.class)) + .withUserConfiguration(EmbeddedDataSourceConfiguration.class).run((context) -> { + BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("dslContext"); + assertThat(beanDefinition.getDependsOn()).containsExactly("liquibase"); + }); + } + + @Test + void whenCustomSpringLiquibaseIsDefinedThenJooqDslContextDependsOnSpringLiquibaseBeans() { + this.contextRunner.withConfiguration(AutoConfigurations.of(JooqAutoConfiguration.class)) + .withUserConfiguration(LiquibaseUserConfiguration.class, EmbeddedDataSourceConfiguration.class) + .run((context) -> { + BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition("dslContext"); + assertThat(beanDefinition.getDependsOn()).containsExactly("springLiquibase"); + }); + } + private ContextConsumer assertLiquibase(Consumer consumer) { return (context) -> { assertThat(context).hasSingleBean(SpringLiquibase.class);