【问题标题】:spring boot hikari config not loadedspring boot hikari 配置未加载
【发布时间】:2022-09-29 21:51:18
【问题描述】:

我正在使用 spring boot 2.6.7 和 hikari 池。

我正在尝试使用自动配置和设置:

spring:
  datasource:
    url: \"jdbc:postgresql://localhost:5432/bdd\"
    username: username
    password: pass
    type: app.CustomHikariDatasource
    driver-class-name: org.postgresql.Driver
    hikari:
      maximum-pool-size: 3
      minimum-idle: 3
      register-mbeans: true

但是当应用程序启动时,池始终为 10(默认 hikari 值)

我尝试禁用自动配置(DataSourceAutoConfiguration.class)并像这样手动创建我的数据源:

@Bean
@Primary
public DataSource dataSource(HikariConfig hikariConfig) {
  return new CustomHikariDatasource(hikariConfig);
}

@Bean
@Primary
@ConfigurationProperties(prefix = \"spring.datasource.hikari\")
public HikariConfig hikariConfig() {
  return new HikariConfig();
}

但是当应用程序开始时我得到了:

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [HikariDataSource (HikariPool-1)] with key \'dataSource\'; nested exception is javax.management.InstanceAlreadyExistsException: MXBean already registered with name com.zaxxer.hikari:type=PoolConfig (HikariPool-1)

如果我在 HikariConfig 构造函数中放置一个断点,我将有效地传递 2 次! 如果我禁用 register-mbeans: false 它可以工作,但我需要激活 mbeans!

找到解决方案的 2 种方法:

  • 首先,有人可以向我解释一下为什么我的自动配置不采用 hikariconfig 属性并可能解决问题吗?
  • 其次,如果第一点不起作用,为什么当我禁用自动配置时 spring boot 实例化 2 次 hikariconfig?我需要禁用其他东西吗?

谢谢你帮助我。

#编辑1

要禁用默认 mbean 导出器,我遵循此问题:

https://github.com/brettwooldridge/HikariCP/issues/342

这样做:

@Bean
public MBeanExporter exporter() {
  MBeanExporter exporter = new MBeanExporter();
  exporter.setAutodetect(true);
  exporter.setExcludedBeans(\"dataSource\");
  return exporter;
}

我不再有异常,我的 mbean 已正确暴露!

#EDIT2

对于第一点,我认为这是因为我正在使用 CustomHikariDatasource 并且在 DatasourceConfiguration 的代码中我可以看到:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HikariDataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = \"spring.datasource.type\", havingValue = \"com.zaxxer.hikari.HikariDataSource\",
        matchIfMissing = true)
static class Hikari {

所以因为我的 spring.datasource.type 不是 com.zaxxer.hikari.HikariDataSource,spring 没有以正确的方式实例化它,所以我决定禁用自动配置并手动实例化我的 CustomHikariDatasource,并使用在Edit1,一切似乎都在工作。

  • 您不使用 Spring 是有原因的吗?你的CustomHikariDataSource 有什么特别之处?还要确保你的CustomHikariDataSource 没有用@Component 注释,这将创建2个实例,这也可能是由于你创建了自己的bean,你得到了一个代理,它也会调用构造函数两次。尽管如此,我强烈建议使用自动配置而不是禁用它。
  • 不,我的 CustomHikariDatasource 没有@component,我需要使用自定义的方法来覆盖 getConnection 方法并添加租户前缀架构,因为它是一个多租户基础架构应用程序,这是我找到的唯一方法.查看我的更新 1 以了解我找到的解决第二点的方法
  • 好的,我知道如何禁用 spring 之一,但是我怎样才能禁用 hikari 呢?
  • 所以基本上是双重注册的问题。我不建议覆盖 MBeanExporter 实际上你正在破坏事情,因为默认是 AnnotationMBeanExporter 正在使用。相反,我建议创建添加@EnableMBeanExport(registrationPolicy=IGNORE_EXISTING)。这将只是跳过注册而不是创建一个新的。

标签: spring-boot hikaricp


【解决方案1】:

正如this issue 中提到的,这是由于 Hikari 中的更改导致 Spring 将其检测为 MBean 并尝试将其导出。但是,当您在 Hikari 上启用 jmx 导出时,已经有一个 bean。

最初的想法可能是通过在配置中指定它来禁用 Hikari 中的 JMX 导出。

spring.datasource.hikari.register-mbeans=false

但是根据前面提到的问题,这只会在 JMX 中注册数据源。而 Hikari 本身在 JMX 中导出了两个。

我建议将@EnableMBeanExport 注释添加到配置类中,并在检测到现有bean 时覆盖该行为。默认是抛出异常,但您可以将其配置为忽略异常并保留原始 bean。

@EnableMBeanExport(registration=IGNORE_EXISTING)

这将启用 JMX 导出(因为它已经启用)并保留 Hikari 注册的。

【讨论】:

    猜你喜欢
    • 2019-10-28
    • 2019-02-03
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 2015-11-19
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多