Allow user to replace auto-configured Data JDBC beans
Closes gh-32571
This commit is contained in:
parent
7c4e46e538
commit
0ae7e935c3
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.data.jdbc;
|
package org.springframework.boot.autoconfigure.data.jdbc;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
|
@ -28,11 +29,22 @@ import org.springframework.boot.autoconfigure.domain.EntityScanner;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
|
||||||
|
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
|
||||||
|
import org.springframework.data.jdbc.core.convert.JdbcConverter;
|
||||||
|
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
|
||||||
|
import org.springframework.data.jdbc.core.convert.RelationResolver;
|
||||||
|
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||||
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
|
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
|
||||||
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
|
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
|
||||||
import org.springframework.data.jdbc.repository.config.JdbcRepositoryConfigExtension;
|
import org.springframework.data.jdbc.repository.config.JdbcRepositoryConfigExtension;
|
||||||
|
import org.springframework.data.relational.RelationalManagedTypes;
|
||||||
|
import org.springframework.data.relational.core.dialect.Dialect;
|
||||||
|
import org.springframework.data.relational.core.mapping.NamingStrategy;
|
||||||
import org.springframework.data.relational.core.mapping.Table;
|
import org.springframework.data.relational.core.mapping.Table;
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
@ -79,6 +91,59 @@ public class JdbcRepositoriesAutoConfiguration {
|
||||||
return new EntityScanner(this.applicationContext).scan(Table.class);
|
return new EntityScanner(this.applicationContext).scan(Table.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public RelationalManagedTypes jdbcManagedTypes() throws ClassNotFoundException {
|
||||||
|
return super.jdbcManagedTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public JdbcMappingContext jdbcMappingContext(Optional<NamingStrategy> namingStrategy,
|
||||||
|
JdbcCustomConversions customConversions, RelationalManagedTypes jdbcManagedTypes) {
|
||||||
|
return super.jdbcMappingContext(namingStrategy, customConversions, jdbcManagedTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public JdbcConverter jdbcConverter(JdbcMappingContext mappingContext, NamedParameterJdbcOperations operations,
|
||||||
|
@Lazy RelationResolver relationResolver, JdbcCustomConversions conversions, Dialect dialect) {
|
||||||
|
return super.jdbcConverter(mappingContext, operations, relationResolver, conversions, dialect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public JdbcCustomConversions jdbcCustomConversions() {
|
||||||
|
return super.jdbcCustomConversions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public JdbcAggregateTemplate jdbcAggregateTemplate(ApplicationContext applicationContext,
|
||||||
|
JdbcMappingContext mappingContext, JdbcConverter converter, DataAccessStrategy dataAccessStrategy) {
|
||||||
|
return super.jdbcAggregateTemplate(applicationContext, mappingContext, converter, dataAccessStrategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations operations,
|
||||||
|
JdbcConverter jdbcConverter, JdbcMappingContext context, Dialect dialect) {
|
||||||
|
return super.dataAccessStrategyBean(operations, jdbcConverter, context, dialect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public Dialect jdbcDialect(NamedParameterJdbcOperations operations) {
|
||||||
|
return super.jdbcDialect(operations);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.function.Function;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Answers;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||||
|
@ -32,16 +33,24 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerA
|
||||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration;
|
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.domain.ManagedTypes;
|
import org.springframework.data.domain.ManagedTypes;
|
||||||
|
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
|
||||||
|
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
|
||||||
|
import org.springframework.data.jdbc.core.convert.JdbcConverter;
|
||||||
|
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
|
||||||
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
|
||||||
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
|
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
|
||||||
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
|
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
|
||||||
|
import org.springframework.data.relational.RelationalManagedTypes;
|
||||||
|
import org.springframework.data.relational.core.dialect.Dialect;
|
||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link JdbcRepositoriesAutoConfiguration}.
|
* Tests for {@link JdbcRepositoriesAutoConfiguration}.
|
||||||
|
@ -128,6 +137,56 @@ class JdbcRepositoriesAutoConfigurationTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsUserToDefineCustomRelationalManagedTypes() {
|
||||||
|
allowsUserToDefineCustomBean(RelationalManagedTypesConfiguration.class, RelationalManagedTypes.class,
|
||||||
|
"customRelationalManagedTypes");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsUserToDefineCustomJdbcMappingContext() {
|
||||||
|
allowsUserToDefineCustomBean(JdbcMappingContextConfiguration.class, JdbcMappingContext.class,
|
||||||
|
"customJdbcMappingContext");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsUserToDefineCustomJdbcConverter() {
|
||||||
|
allowsUserToDefineCustomBean(JdbcConverterConfiguration.class, JdbcConverter.class, "customJdbcConverter");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsUserToDefineCustomJdbcCustomConversions() {
|
||||||
|
allowsUserToDefineCustomBean(JdbcCustomConversionsConfiguration.class, JdbcCustomConversions.class,
|
||||||
|
"customJdbcCustomConversions");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsUserToDefineCustomJdbcAggregateTemplate() {
|
||||||
|
allowsUserToDefineCustomBean(JdbcAggregateTemplateConfiguration.class, JdbcAggregateTemplate.class,
|
||||||
|
"customJdbcAggregateTemplate");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsUserToDefineCustomDataAccessStrategy() {
|
||||||
|
allowsUserToDefineCustomBean(DataAccessStrategyConfiguration.class, DataAccessStrategy.class,
|
||||||
|
"customDataAccessStrategy");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowsUserToDefineCustomDialect() {
|
||||||
|
allowsUserToDefineCustomBean(DialectConfiguration.class, Dialect.class, "customDialect");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void allowsUserToDefineCustomBean(Class<?> configuration, Class<?> beanType, String beanName) {
|
||||||
|
this.contextRunner.with(database())
|
||||||
|
.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
|
||||||
|
DataSourceTransactionManagerAutoConfiguration.class))
|
||||||
|
.withUserConfiguration(configuration, EmptyConfiguration.class).run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(beanType);
|
||||||
|
assertThat(context).hasBean(beanName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private Function<ApplicationContextRunner, ApplicationContextRunner> database() {
|
private Function<ApplicationContextRunner, ApplicationContextRunner> database() {
|
||||||
return (runner) -> runner
|
return (runner) -> runner
|
||||||
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
|
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
|
||||||
|
@ -154,4 +213,74 @@ class JdbcRepositoriesAutoConfigurationTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class RelationalManagedTypesConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RelationalManagedTypes customRelationalManagedTypes() {
|
||||||
|
return RelationalManagedTypes.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class JdbcMappingContextConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
JdbcMappingContext customJdbcMappingContext() {
|
||||||
|
return mock(JdbcMappingContext.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class JdbcConverterConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
JdbcConverter customJdbcConverter() {
|
||||||
|
return mock(JdbcConverter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class JdbcCustomConversionsConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
JdbcCustomConversions customJdbcCustomConversions() {
|
||||||
|
return mock(JdbcCustomConversions.class, Answers.RETURNS_MOCKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class JdbcAggregateTemplateConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
JdbcAggregateTemplate customJdbcAggregateTemplate() {
|
||||||
|
return mock(JdbcAggregateTemplate.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class DataAccessStrategyConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
DataAccessStrategy customDataAccessStrategy() {
|
||||||
|
return mock(DataAccessStrategy.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class DialectConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
Dialect customDialect() {
|
||||||
|
return mock(Dialect.class, Answers.RETURNS_MOCKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue