简体   繁体   English

仅按需启用 R2DBC 配置

[英]Enable R2DBC configuration only on demand

I'm working on a library that is consumed by some other project.我正在开发一个由其他项目使用的库。 The library offers database access through JDBC and I'd like to add support for R2DBC too in the same library.该库通过 JDBC 提供数据库访问,我也想在同一个库中添加对 R2DBC 的支持。 The consuming project should be able to switch between JDBC and R2DBC based on a configuration property.消费项目应该能够基于配置属性在 JDBC 和 R2DBC 之间切换。

The problem that I'm facing is that the R2DBC auto-configuration provided by spring-boot-starter-data-r2dbc (2.5.4) overrides the JDBC configuration and the consuming project can only work with R2DBC.我面临的问题是spring-boot-starter-data-r2dbc (2.5.4) 提供的 R2DBC 自动配置覆盖了 JDBC 配置,而消费项目只能与 R2DBC 一起使用。

Further more, when the project is being built, there are certain tasks like documentation or code generation, tests, etc, that depend on the spring context being loaded but do not require database access.此外,在构建项目时,某些任务(如文档或代码生成、测试等)依赖于正在加载的 spring 上下文,但不需要数据库访问。 These tasks fail because the context cannot be loaded due to the missing R2DBC properties:这些任务失败,因为由于缺少 R2DBC 属性而无法加载上下文:

BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [org/springframework/boot/autoconfigure/r2dbc/ConnectionFactoryConfigurations$Pool.class]: Bean instantiation via factory method failed;
 nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.r2dbc.pool.ConnectionPool]: Factory method 'connectionFactory' threw exception; 
 nested exception is org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsInitializer$ConnectionFactoryBeanCreationException: Failed to determine a suitable R2DBC Connection URL

Of course, I could specify the required properties, but it doesn't feel right to load components I don't use.当然,我可以指定所需的属性,但是加载我不使用的组件感觉不对。 I would like to disable R2DBC completely (much like you can disable Vault support with spring.cloud.vault.enabled=false ) and only load it when I need it.我想完全禁用 R2DBC(就像您可以使用spring.cloud.vault.enabled=false禁用 Vault 支持一样)并且仅在需要时才加载它。 Any ideas on how to do that?关于如何做到这一点的任何想法?

My first attempt was to create a configuration class in the library:我的第一次尝试是在库中创建配置 class:

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "r2dbc.enabled", havingValue = "false", matchIfMissing = true)
@AutoConfigureBefore(R2dbcAutoConfiguration.class)
@EnableAutoConfiguration(exclude = R2dbcAutoConfiguration.class)
public class R2dbcConfig {}

That did the trick for some of the tasks but caused problems in other.这对某些任务起到了作用,但在其他任务中却引起了问题。 I'm posting it as it may be sufficient for some folks.我发布它,因为它可能对某些人来说已经足够了。

The solution that works in all my cases was a bit more involved, I had to implement an EnvironmentPostProcessor that adds org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration to the spring.autoconfigure.exclude property.在我所有情况下都适用的解决方案涉及更多,我必须实现一个EnvironmentPostProcessor ,将org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration添加到spring.autoconfigure.exclude属性。 Shortly, something like this:很快,就像这样:

public class R2dbcDisablerEnvironmentPostProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Properties props = new Properties();
        props.setProperty("spring.autoconfigure.exclude", "org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration");

        environment.getPropertySources()
                .addLast(new PropertiesPropertySource("r2dbcProperties", props));
    }
}

Thanks @xerx593 for the pointers!感谢@xerx593 的指点!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM