You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成Oracle AQ:如何通过application.yaml配置Oracle UCP

Spring Boot集成Oracle AQ时Oracle UCP配置不生效问题

问题场景

我在Spring Boot中集成Oracle AQ的方式如下:

Gradle依赖

implementation "com.oracle.database.spring:oracle-spring-boot-starter-aqjms:23.4.0"

JmsConfiguration初始配置

@Configuration
@EnableJms
public class JmsConfiguration {

    @Bean
    public ConnectionFactory connectionFactory(DataSource dataSource) {
        return AQjmsFactory.getQueueConnectionFactory(dataSource);
    }
}

尝试通过application.yaml配置Oracle UCP属性,但属性未生效:

spring:
  datasource:
    url: jdbc:oracle:thin:@localhost:1521/ORCLPDB1
    username: AQ_USER
    password: your_password
    oracleucp:
      initial-pool-size: 5
      min-pool-size: 10
      max-pool-size: 30
      connection-wait-timeout: 2
      connection-factory-class-name: oracle.jdbc.pool.OracleDataSource
      connection-pool-name: some_pool_name
    type: oracle.ucp.jdbc.PoolDataSource

但通过Java代码直接设置属性则正常生效:

import jakarta.jms.ConnectionFactory;
import jakarta.jms.JMSException;
import oracle.jakarta.jms.AQjmsFactory;
import oracle.ucp.jdbc.PoolDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;

import java.sql.SQLException;

@Configuration
@EnableJms
public class JmsConfiguration {

    @Bean
    public ConnectionFactory connectionFactory(PoolDataSource poolDataSource) throws JMSException, SQLException {
        poolDataSource.setInitialPoolSize(5);
        poolDataSource.setMinPoolSize(10);
        poolDataSource.setMaxPoolSize(30);
        poolDataSource.setConnectionWaitTimeout(3000);

        return AQjmsFactory.getQueueConnectionFactory(poolDataSource);
    }
}

验证代码及结果

使用以下代码验证配置是否生效:

import oracle.ucp.jdbc.PoolDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.context.event.EventListener;

import java.sql.SQLException;

@SpringBootApplication
@ConfigurationPropertiesScan
public class RequestBufferingServiceApplication {

    @Autowired
    PoolDataSource poolDataSource;

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

    @EventListener(ApplicationReadyEvent.class)
    public void foo() throws SQLException {
        System.out.println("------");
        System.out.println("Init pool size: " + poolDataSource.getInitialPoolSize());
        System.out.println("Min pool size: " + poolDataSource.getMinPoolSize());
        System.out.println("Max pool size: " + poolDataSource.getMaxPoolSize());
        System.out.println("ConnectionWaitTimeout: " + poolDataSource.getConnectionWaitTimeout());
        System.out.println("------");
    }
}
  • YAML配置未生效时的输出:
------
Init pool size: 0
Min pool size: 0
Max pool size: 2147483647
ConnectionWaitTimeout: 3
------
  • 代码配置生效时的预期输出:
------
Init pool size: 5
Min pool size: 10
Max pool size: 30
ConnectionWaitTimeout: 2
------

项目配置及启动日志

build.gradle配置:

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.3'
    id 'io.spring.dependency-management' version '1.1.6'
    id 'io.freefair.lombok' version '8.11'
    id "io.qameta.allure-report" version "2.11.2"
    id 'org.sonarqube' version '5.0.0.4638'
    id 'jacoco'
}

group = 'de.telekom.mff'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

bootJar {
    archiveFileName = "request-buffering-service.${archiveExtension.get()}"
}

jar {
    enabled = true
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

ext {
    versions = [
            oracleSpringBootStarterAqjms: "23.4.0",
            allureCucumber7Jvm          : "2.27.0",
            testcontainers              : "1.20.1",
            springCloud                 : "2023.0.3",
            awaitility                  : "4.2.2",
            xmlUnit                     : "2.10.0",
            jsonUnitAssertj             : "3.2.2",
            wiremock                    : "4.1.4"
    ]
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${versions.springCloud}"
    }
}

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-web"
    implementation "org.springframework.boot:spring-boot-starter-webflux"
    implementation "org.springframework.boot:spring-boot-starter-log4j2"
    implementation "org.springframework.boot:spring-boot-starter-actuator"
    implementation "org.springframework:spring-aspects"
    implementation "org.springframework.cloud:spring-cloud-starter-kubernetes-fabric8-config"
    implementation "org.springframework.cloud:spring-cloud-kubernetes-fabric8-leader"
    implementation "com.oracle.database.spring:oracle-spring-boot-starter-aqjms:${versions.oracleSpringBootStarterAqjms}"
    testImplementation "org.springframework.boot:spring-boot-starter-test"
    testImplementation "io.fabric8:kubernetes-server-mock"
    testImplementation "org.springframework.cloud:spring-cloud-contract-wiremock:${versions.wiremock}"
    testImplementation "org.testcontainers:oracle-free:${versions.testcontainers}"
    testImplementation "org.testcontainers:junit-jupiter:${versions.testcontainers}"
    testImplementation "org.awaitility:awaitility:${versions.awaitility}"
    testImplementation "org.xmlunit:xmlunit-core:${versions.xmlUnit}"
    testImplementation "io.qameta.allure:allure-cucumber7-jvm:${versions.allureCucumber7Jvm}"
    testImplementation "net.javacrumbs.json-unit:json-unit-assertj:${versions.jsonUnitAssertj}"
    testRuntimeOnly "org.junit.platform:junit-platform-launcher"
}

Spring启动调试日志(部分):

Negative matches:
DataSourceAutoConfiguration:
Did not match:

  • @ConditionalOnClass did not find required class 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType'
    (OnClassCondition)

DataSourceInitializationConfiguration:
Did not match:

  • @ConditionalOnClass did not find required class 'org.springframework.jdbc.datasource.init.DatabasePopulator'
    (OnClassCondition)

DataSourceTransactionManagerAutoConfiguration:
Did not match:

  • @ConditionalOnClass did not find required class 'org.springframework.jdbc.core.JdbcTemplate' (OnClassCondition)

解决方案

问题原因

从启动日志的Negative matches可以看出,Spring Boot的DataSourceAutoConfiguration等相关自动配置类未触发,原因是缺少spring-boot-starter-jdbc依赖——Oracle AQ JMS Starter没有自动引入JDBC Starter,导致Spring无法自动绑定UCP的配置属性到PoolDataSource实例。

另外,connection-wait-timeout在UCP配置中单位是秒,但通过代码设置时用的是毫秒(3000对应3秒),需要注意配置值的单位一致性。

修复步骤

  1. 添加JDBC Starter依赖
    在build.gradle的dependencies中加入:
implementation "org.springframework.boot:spring-boot-starter-jdbc"
  1. 修正application.yaml配置
    确保配置结构正确,并且注意connection-wait-timeout的单位:
spring:
  datasource:
    url: jdbc:oracle:thin:@localhost:1521/ORCLPDB1
    username: AQ_USER
    password: your_password
    type: oracle.ucp.jdbc.PoolDataSource
    oracleucp:
      initial-pool-size: 5
      min-pool-size: 10
      max-pool-size: 30
      connection-wait-timeout: 3 # 单位为秒,对应代码中的3000毫秒
      connection-factory-class-name: oracle.jdbc.pool.OracleDataSource
      connection-pool-name: some_pool_name
  1. 简化JmsConfiguration配置
    不需要再手动设置UCP属性,Spring会自动绑定配置到PoolDataSource:
@Configuration
@EnableJms
public class JmsConfiguration {

    @Bean
    public ConnectionFactory connectionFactory(PoolDataSource poolDataSource) throws JMSException {
        return AQjmsFactory.getQueueConnectionFactory(poolDataSource);
    }
}

验证

重启应用后,运行验证代码,输出应该和预期一致:

------
Init pool size: 5
Min pool size: 10
Max pool size: 30
ConnectionWaitTimeout: 3
------

内容的提问来源于stack exchange,提问作者Georgii Lvov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 04:52:03