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秒),需要注意配置值的单位一致性。
修复步骤
- 添加JDBC Starter依赖
在build.gradle的dependencies中加入:
implementation "org.springframework.boot:spring-boot-starter-jdbc"
- 修正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
- 简化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
相关产品推荐
相关产品推荐

