Generalize database initialization detection and include R2DBC

Closes gh-25818
This commit is contained in:
Andy Wilkinson
2021-03-29 19:02:40 +01:00
parent 22b02a6c6f
commit 9b65409e23
34 changed files with 297 additions and 236 deletions

View File

@@ -50,7 +50,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.jdbc.init.dependency.DataSourceInitializationDependencyConfigurer;
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@@ -88,7 +88,7 @@ import org.springframework.util.StringUtils;
@ConditionalOnProperty(prefix = "spring.flyway", name = "enabled", matchIfMissing = true)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, JdbcTemplateAutoConfiguration.class,
HibernateJpaAutoConfiguration.class })
@Import(DataSourceInitializationDependencyConfigurer.class)
@Import(DatabaseInitializationDependencyConfigurer.class)
public class FlywayAutoConfiguration {
@Bean

View File

@@ -19,18 +19,18 @@ package org.springframework.boot.autoconfigure.flyway;
import java.util.Collections;
import java.util.Set;
import org.springframework.boot.jdbc.init.dependency.AbstractBeansOfTypeDataSourceInitializerDetector;
import org.springframework.boot.jdbc.init.dependency.DataSourceInitializerDetector;
import org.springframework.boot.sql.init.dependency.AbstractBeansOfTypeDatabaseInitializerDetector;
import org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector;
/**
* A {@link DataSourceInitializerDetector} for {@link FlywayMigrationInitializer}.
* A {@link DatabaseInitializerDetector} for {@link FlywayMigrationInitializer}.
*
* @author Andy Wilkinson
*/
class FlywayMigrationInitializerDataSourceInitializerDetector extends AbstractBeansOfTypeDataSourceInitializerDetector {
class FlywayMigrationInitializerDatabaseInitializerDetector extends AbstractBeansOfTypeDatabaseInitializerDetector {
@Override
protected Set<Class<?>> getDataSourceInitializerBeanTypes() {
protected Set<Class<?>> getDatabaseInitializerBeanTypes() {
return Collections.singleton(FlywayMigrationInitializer.class);
}

View File

@@ -42,8 +42,8 @@ import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.jdbc.init.dependency.DataSourceInitializationDependencyConfigurer;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.DependsOn;
@@ -85,7 +85,7 @@ class DataSourceInitializationConfiguration {
// Fully-qualified to work around javac bug in JDK 1.8
@org.springframework.context.annotation.Configuration(proxyBeanMethods = false)
@org.springframework.context.annotation.Conditional(DifferentCredentialsCondition.class)
@org.springframework.context.annotation.Import(DataSourceInitializationDependencyConfigurer.class)
@org.springframework.context.annotation.Import(DatabaseInitializationDependencyConfigurer.class)
@ConditionalOnSingleCandidate(DataSource.class)
@ConditionalOnMissingBean(DataSourceScriptDatabaseInitializer.class)
static class InitializationSpecificCredentialsDataSourceInitializationConfiguration {
@@ -141,7 +141,7 @@ class DataSourceInitializationConfiguration {
// Fully-qualified to work around javac bug in JDK 1.8
@org.springframework.context.annotation.Configuration(proxyBeanMethods = false)
@org.springframework.context.annotation.Import(DataSourceInitializationDependencyConfigurer.class)
@org.springframework.context.annotation.Import(DatabaseInitializationDependencyConfigurer.class)
@org.springframework.context.annotation.Conditional(DataSourceInitializationCondition.class)
@ConditionalOnSingleCandidate(DataSource.class)
@ConditionalOnMissingBean(DataSourceScriptDatabaseInitializer.class)

View File

@@ -19,7 +19,7 @@ package org.springframework.boot.autoconfigure.jdbc;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
import org.springframework.boot.jdbc.init.dependency.DependsOnDataSourceInitializationDetector;
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector;
import org.springframework.jdbc.core.JdbcOperations;
/**
@@ -33,7 +33,7 @@ import org.springframework.jdbc.core.JdbcOperations;
* @author Andrii Hrytsiuk
* @since 2.0.4
* @see BeanDefinition#setDependsOn(String[])
* @deprecated since 2.5.0 in favor of {@link DependsOnDataSourceInitializationDetector}
* @deprecated since 2.5.0 in favor of {@link DependsOnDatabaseInitializationDetector}
*/
@Deprecated
public class JdbcOperationsDependsOnPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor {

View File

@@ -23,7 +23,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.init.dependency.DataSourceInitializationDependencyConfigurer;
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -44,7 +44,7 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(JdbcProperties.class)
@Import({ DataSourceInitializationDependencyConfigurer.class, JdbcTemplateConfiguration.class,
@Import({ DatabaseInitializationDependencyConfigurer.class, JdbcTemplateConfiguration.class,
NamedParameterJdbcTemplateConfiguration.class })
public class JdbcTemplateAutoConfiguration {

View File

@@ -19,7 +19,7 @@ package org.springframework.boot.autoconfigure.jdbc;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
import org.springframework.boot.jdbc.init.dependency.DependsOnDataSourceInitializationDetector;
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
/**
@@ -31,7 +31,7 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
* @author Andrii Hrytsiuk
* @since 2.1.4
* @see BeanDefinition#setDependsOn(String[])
* @deprecated since 2.5.0 in favor of {@link DependsOnDataSourceInitializationDetector}
* @deprecated since 2.5.0 in favor of {@link DependsOnDatabaseInitializationDetector}
*/
@Deprecated
public class NamedParameterJdbcOperationsDependsOnPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor {

View File

@@ -21,7 +21,7 @@ import org.jooq.DSLContext;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
import org.springframework.boot.jdbc.init.dependency.DependsOnDataSourceInitializationDetector;
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector;
/**
* {@link BeanFactoryPostProcessor} that can be used to dynamically declare that all
@@ -30,7 +30,7 @@ import org.springframework.boot.jdbc.init.dependency.DependsOnDataSourceInitiali
* @author Eddú Meléndez
* @since 2.3.9
* @see BeanDefinition#setDependsOn(String[])
* @deprecated since 2.5.0 in favor of {@link DependsOnDataSourceInitializationDetector}
* @deprecated since 2.5.0 in favor of {@link DependsOnDatabaseInitializationDetector}
*/
@Deprecated
public class DslContextDependsOnPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor {

View File

@@ -34,7 +34,7 @@ import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfigurati
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.init.dependency.DataSourceInitializationDependencyConfigurer;
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@@ -63,7 +63,7 @@ import org.springframework.util.StringUtils;
@ConditionalOnProperty(prefix = "spring.liquibase", name = "enabled", matchIfMissing = true)
@Conditional(LiquibaseDataSourceCondition.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
@Import(DataSourceInitializationDependencyConfigurer.class)
@Import(DatabaseInitializationDependencyConfigurer.class)
public class LiquibaseAutoConfiguration {
@Bean

View File

@@ -22,19 +22,16 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.jdbc.init.dependency.DataSourceInitializationDependencyConfigurer;
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.util.StringUtils;
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(AbstractScriptDatabaseInitializer.class)
@ConditionalOnSingleCandidate(DataSource.class)
@Import(DataSourceInitializationDependencyConfigurer.class)
class DataSourceInitializationConfiguration {
@Bean

View File

@@ -24,6 +24,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@@ -38,7 +39,8 @@ import org.springframework.context.annotation.Import;
@ConditionalOnProperty(prefix = "spring.sql.init", name = "enabled", matchIfMissing = true)
@AutoConfigureAfter({ R2dbcAutoConfiguration.class, DataSourceAutoConfiguration.class })
@EnableConfigurationProperties(SqlInitializationProperties.class)
@Import({ R2dbcInitializationConfiguration.class, DataSourceInitializationConfiguration.class })
@Import({ DatabaseInitializationDependencyConfigurer.class, R2dbcInitializationConfiguration.class,
DataSourceInitializationConfiguration.class })
public class SqlInitializationAutoConfiguration {
}

View File

@@ -173,5 +173,5 @@ org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityPr
org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider
# DataSource initializer detectors
org.springframework.boot.jdbc.init.dependency.DataSourceInitializerDetector=\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializerDataSourceInitializerDetector
org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializerDatabaseInitializerDetector

View File

@@ -44,7 +44,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.jdbc.init.dependency.DependsOnDataSourceInitialization;
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -283,7 +283,7 @@ class DataSourceAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
@DependsOnDataSourceInitialization
@DependsOnDatabaseInitialization
static class TestInitializedDataSourceConfiguration {
private boolean called;

View File

@@ -59,10 +59,10 @@ import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurat
import org.springframework.boot.autoconfigure.orm.jpa.mapping.NonAnnotatedEntity;
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration;
import org.springframework.boot.jdbc.init.dependency.DependsOnDataSourceInitialization;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.orm.jpa.hibernate.SpringJtaPlatform;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.context.ApplicationEvent;
@@ -501,7 +501,7 @@ class HibernateJpaAutoConfigurationTests extends AbstractJpaAutoConfigurationTes
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(City.class)
@DependsOnDataSourceInitialization
@DependsOnDatabaseInitialization
static class TestInitializedJpaConfiguration {
private boolean called;

View File

@@ -24,6 +24,7 @@ import javax.sql.DataSource;
import io.r2dbc.spi.ConnectionFactory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
@@ -31,6 +32,7 @@ import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
import org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializer;
import org.springframework.boot.sql.init.AbstractScriptDatabaseInitializer;
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
import org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitialization;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -98,6 +100,28 @@ public class SqlInitializationAutoConfigurationTests {
.hasBean("customInitializer"));
}
@Test
void whenBeanIsAnnotatedAsDependingOnDatabaseInitializationThenItDependsOnR2dbcScriptDatabaseInitializer() {
this.contextRunner.withConfiguration(AutoConfigurations.of(R2dbcAutoConfiguration.class))
.withUserConfiguration(DependsOnInitializedDatabaseConfiguration.class).run((context) -> {
BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition(
"sqlInitializationAutoConfigurationTests.DependsOnInitializedDatabaseConfiguration");
assertThat(beanDefinition.getDependsOn())
.containsExactlyInAnyOrder("r2dbcScriptDatabaseInitializer");
});
}
@Test
void whenBeanIsAnnotatedAsDependingOnDatabaseInitializationThenItDependsOnDataSourceScriptDatabaseInitializer() {
this.contextRunner.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class))
.withUserConfiguration(DependsOnInitializedDatabaseConfiguration.class).run((context) -> {
BeanDefinition beanDefinition = context.getBeanFactory().getBeanDefinition(
"sqlInitializationAutoConfigurationTests.DependsOnInitializedDatabaseConfiguration");
assertThat(beanDefinition.getDependsOn())
.containsExactlyInAnyOrder("dataSourceScriptDatabaseInitializer");
});
}
@Configuration(proxyBeanMethods = false)
static class DatabaseInitializerConfiguration {
@@ -116,4 +140,14 @@ public class SqlInitializationAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
@DependsOnDatabaseInitialization
static class DependsOnInitializedDatabaseConfiguration {
DependsOnInitializedDatabaseConfiguration() {
}
}
}