Allow user to replace auto-configured Data JDBC beans

Closes gh-32571
pull/32585/head
Andy Wilkinson 2 years ago
parent 7c4e46e538
commit 0ae7e935c3

@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.data.jdbc;
import java.util.Optional;
import java.util.Set;
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.JdbcTemplateAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.EnableJdbcRepositories;
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.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.transaction.PlatformTransactionManager;
@ -79,6 +91,59 @@ public class JdbcRepositoriesAutoConfiguration {
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 org.junit.jupiter.api.Test;
import org.mockito.Answers;
import org.springframework.boot.autoconfigure.AutoConfigurations;
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.sql.init.SqlInitializationAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.repository.config.AbstractJdbcConfiguration;
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.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* 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() {
return (runner) -> runner
.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…
Cancel
Save