【问题标题】:Spring Boot application is ignoring hikaricp configSpring Boot 应用程序忽略 hikaricp 配置
【发布时间】:2022-03-15 05:37:05
【问题描述】:

我是 * 的新手,但在这里阅读了大量帖子,现在卡住了。我的 application.properties 已阅读,但用于配置 hikaricp 的部分被忽略/无效。

我阅读了https://www.javadevjournal.com/spring-boot/spring-boot-hikari/ 并按照那里的步骤进行操作,仍然成功。

pom.xml

    <dependencies>  
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>5.4.10.Final</version>
        <exclusions>
            <exclusion>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache</artifactId>
            </exclusion>
        </exclusions>
    </dependency>    
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-jcache</artifactId>
        <version>5.4.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>3.6.3</version>
    </dependency>        
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
            </exclusion>                
        </exclusions>
        <version>2.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <exclusions>
         <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
          </exclusion>
        </exclusions>
        <version>2.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
         <exclusion>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
          </exclusion>
        </exclusions>
        <version>2.2.2.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <exclusions>
    <exclusion>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
          </exclusion>
        </exclusions>
        <scope>test</scope>
        <version>2.2.2.RELEASE</version>
    </dependency>

application.properties

    spring.cache.jcache.config=classpath:ehcache.xml
    spring.datasource.jdbc-url=jdbc:postgresql://VOC-APP202-db:5432/voice-app
    spring.datasource.username=vocapp202
    spring.datasource.password=******
    srping.datasource.driver-class-name=org.postgresql.Driver       
    spring.datasource.type=com.zaxxer.hikari.HikariDataSource
    spring.datasource.hikari.connectionTimeout=1000
    spring.datasource.hikari.idleTimeout=30000
    spring.datasource.hikari.maxLifetime=60000
    spring.datasource.hikari.connectionTestQuery=SELECT * FROM table where id=1
    spring.datasource.hikari.minimumIdle=1
    spring.datasource.hikari.maximumPoolSize=5
    spring.datasource.hikari.poolName=voiceapp-db-pool
    spring.datasource.hikari.autoCommit=false

BlacklistApplication.class:

    package de.mycompany.voice.blacklist_ng;  
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.jpa.repository.config.EnableJpaAuditing;   
    @SpringBootApplication
    @EnableJpaAuditing
    @EnableCaching
    @Configuration
    public class BlacklistngApplication {

        public static void main(String[] args) {
            SpringApplication.run(BlacklistngApplication.class, args);
        }

    }

配置类:

    @Configuration
    @ConfigurationProperties("spring.datasource")
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactory",
            basePackages = {"de.firsttelecom.voice.blacklist_ng.repository.vocapp202"}
    )
    public class VocApp202DbConfig extends HikariConfig {

        @Primary
        @Bean(name = "dataSource")
        public DataSource dataSource() {
            return new HikariDataSource(this);
        }

我错过了什么?

【问题讨论】:

  • 如何将多个数据源与属性绑定一起使用在参考指南中有明确的解释。见docs.spring.io/spring-boot/docs/current/reference/html/…
  • 这也适用于三个数据源吗?或更好的 n 源。我有“巨大”的应用程序或来自不同部门的更好的不同数据源,我需要将它们组合在一个应用程序中。
  • 它提到 2 的事实并不意味着它仅限于 2。该机制适用于任意数量的数据源。
  • 很高兴知道,谢谢。
  • 不要将 code/xml/stacktraces 添加为 cmets。那些是不可读的。文档中的解决方案有效,如果它对您不起作用,您正在做推荐方式之外的事情(或禁用自动配置的其他部分)。

标签: spring-boot config hikaricp


【解决方案1】:

如果您已经在使用带有 hikari 和数据源配置的 application.properties 文件,那么当您使用 new HikariDataSource(this) 时,它将覆盖您的 application.properties 值。

您可以手动创建 HikariDataSource 并从 application.properties 中删除:

@Bean(name = "dataSource")
public DataSource dataSource() {
    HikariDataSource hikariDataSource = new HikariDataSource();
    hikariDataSource.setMaximumPoolSize(5);
    hikariDataSource.setMaxLifetime(60000);
    hikariDataSource.setMinimumIdle(1);

    //.. some other configs
    return hikariDataSource;
}

或仅使用 application.properties 值。

【讨论】:

    【解决方案2】:

    spring.datasource.hikari.*(以及spring.datasource.url)属性仅在您使用 Spring Boot DataSource 自动配置时才有效。为了实现它,你需要移除这个bean:

     @Primary
     @Bean(name = "dataSource")
     public DataSource dataSource() {
         return new HikariDataSource(this);
     }
    

    Spring Boot 将使用所有这些属性自动为您创建它。您可以查看DataSourceAutoConfiguration.class了解更多信息。

    如果由于某种原因,您无法删除此 bean(例如,您有另一组数据源,并且您需要创建手动数据源以将其标记为 @Primary),您可以使用“原始”属性配置光。因此,您应该通过删除 hikari. 部分来修改属性,而不是删除 dataSource() 方法:

    ...
    spring.datasource.jdbc-url=jdbc:postgresql://VOC-APP202-db:5432/voice-app
    ...
    spring.datasource.connectionTimeout=1000
    spring.datasource.idleTimeout=30000
    spring.datasource.maxLifetime=60000
    spring.datasource.connectionTestQuery=SELECT * FROM table where id=1
    spring.datasource.minimumIdle=1
    spring.datasource.maximumPoolSize=5
    spring.datasource.poolName=voiceapp-db-pool
    spring.datasource.autoCommit=false
    

    jdbc-url 也是 hikari 特有的属性,这就是它现在起作用的原因。

    总结一下:没有hikari.jdbc-url 的属性用于手动创建的数据源bean,以及带有hikari.url 的属性用于Spring Boot DataSource 自动配置。

    【讨论】:

    【解决方案3】:

    但有些东西不适用于 application.properties,所以我现在做了: DbConfig.class(es)

    @Primary
    @Bean(name = "dataSource")
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig("/hikari_voiceapp.properties");
        //HikariDataSource dataSource = new HikariDataSource(config);
        return new HikariDataSource(config);
    }
    

    并在单独的 hikari.properties 文件中指定每个数据库的所有参数,包括数据库名称:

    hikari_asterisk.properties
    hikari_billing.properties
    hikari_voiceapp.properties
    

    为我工作。

    【讨论】:

      【解决方案4】:

      为了保持标准格式的配置,并且仍然显式地创建数据源,连接池特定的前缀可以用于配置属性。这与使用自动配置时 Spring Boot DataSourceConfiguration 所做的相同:

      @Bean
      @Primary
      @ConfigurationProperties(prefix = "spring.datasource")
      public DataSourceProperties dataSourceProperties() {
          return new DataSourceProperties();
      }
      
      @Bean
      @Primary
      @ConfigurationProperties(prefix = "spring.datasource.hikari")
      public HikariDataSource dataSource(DataSourceProperties properties) {
          HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
          if (StringUtils.hasText(properties.getName())) {
              dataSource.setPoolName(properties.getName());
          }
          return dataSource;
      }
      

      示例application.yaml:

      spring:
        datasource:
          url: jdbc:postgresql://localhost:5432/postgres?gssEncMode=disable
          username: postgres
          password: postgres
          hikari:
            minimumIdle: 0
            maximumPoolSize: 50
            idleTimeout: 90000
            maxLifetime: 900000
            connectionTimeout: 45000
            leakDetectionThreshold: 45000
      

      【讨论】: