创建动态oracle数据源后Springboot创建bean DataSourceConfiguration时出错

问题描述 投票:0回答:1

我将从 1.5.1 升级到 Springboot 3.2.4。源代码正在编译,但我在运行时遇到了一个小问题。在使用 1.5.1 时,我能够创建多个 Oracle 数据源 bean 并使用 springboot Actuator 来获取连接的数据库运行状况。

但是,在 3.2.4 中,启用 DataSourceAutoConfiguration 时,即使我已经注册了两个 Oracle 数据源,我可以在出现以下错误之前在日志中看到这两个数据源:

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class

在出现上述错误之前,我还收到以下警告:

WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext:632 - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pathMappedEndpoints' defined in class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/web/WebEndpointAutoConfiguration.class]: Failed to instantiate [org.springframework.boot.actuate.endpoint.web.PathMappedEndpoints]: Factory method 'pathMappedEndpoints' threw exception with message: Error creating bean with name 'healthEndpoint' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Unsatisfied dependency expressed through method 'healthEndpoint' parameter 0: Error creating bean with name 'healthContributorRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Unsatisfied dependency expressed through method 'healthContributorRegistry' parameter 2: Error creating bean with name 'dbHealthContributor' defined in class path resource [org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.class]: Unsatisfied dependency expressed through method 'dbHealthContributor' parameter 0: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception with message: Failed to determine a suitable driver class

我没有标准的 spring.datasource.* 配置,因为我使用以下 beanPostProcessor 来创建具有自定义配置的数据源。

@Bean
    static BeanDefinitionRegistryPostProcessor beanPostProcessor(final ConfigurableEnvironment environment) {
        return new BeanDefinitionRegistryPostProcessor() {
            public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
                // TODO Auto-generated method stub          
            }

            public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanRegistry) throws BeansException {
                createDynamicBeans(environment,beanRegistry);
                
            }
            
        };
    }

“createDynamicBeans”使用 beanRegistry.registerBeanDefinition 和下面的配置根据配置文件动态创建 bean。

spring.datasource.datasource_1.url=jdbc:<HOST>
spring.datasource.datasource_1.username=<USER>
spring.datasource.datasource_1.password=<PW>
spring.datasource.datasource_1.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.datasource_1.test-on-borrow=true
spring.datasource.datasource_1.validation-query=SELECT 1 from dual
spring.datasource.datasource_1.validation-interval=0

spring.datasource.datasource_2.url=jdbc:<HOST>
spring.datasource.datasource_2.username=<USER>
spring.datasource.datasource_2.password=<PW>
spring.datasource.datasource_2.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.datasource_2.test-on-borrow=true
spring.datasource.datasource_2.validation-query=SELECT 1 from dual
spring.datasource.datasource_2.validation-interval=0

“datasource_1”设置为主

    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'io.springfox:springfox-swagger2:2.10.5'
    implementation 'io.springfox:springfox-swagger-ui:2.4.0'
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.4.0'
    implementation 'javax.annotation:javax.annotation-api:1.3.2'

    implementation 'com.oracle.database.jdbc:ojdbc10:19.22.0.0'
    implementation 'com.oracle.database.security:oraclepki:23.3.0.23.09'
    implementation 'com.oracle.database.security:osdt_core:21.13.0.0'
    implementation 'com.oracle.database.security:osdt_cert:21.13.0.0'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'

我知道这些数据源已成功创建,因为如果我添加以下行,我不会收到任何错误并且可以很好地连接到数据库。

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

但是,“DataSourceHealthIndicator”实例未创建(我认为是因为上面的行),因此我无法在执行器对运行状况的调用中看到数据库的状态。

这是 Springboot 从 1.x 到 3.x 的翻译问题吗?或者是否有另一种方法来创建动态数据源 bean,以便 DataSourceConfiguration 识别它们并且不会搜索默认的 spring.datasource.* 配置(之前在我们的 1.X 版本中未使用过)?

感谢您的帮助!

添加 spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 修复了运行时问题,并且代码能够连接到 Oracle DB,但未创建 DataSourceHealthIndicator bean。

更新 经过进一步调试后,看起来 DataSourceConfiguration 正在尝试创建 HikariDataSource。我的理解是,我已经创建的 BasicDataSource 应该可以防止这种情况发生。为什么 Springboot 无法识别我使用 beanRegistry.registerBeanDefinition 创建的 BasicDataSource?

java spring-boot spring-boot-actuator
1个回答
0
投票

添加以下依赖项似乎已经解决了问题:

providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
implementation 'com.h2database:h2:2.2.220'

我假设 tomcat 运行时正在替换默认的 Hikari CP,并且 h2 lib 正在创建不需要连接字符串的默认数据源。

info 方法现在返回以下内容:

{
    "status": "UP",
    "components": {
        "db": {
            "status": "UP",
            "components": {
                "dataSource": {
                    "status": "UP",
                    "details": {
                        "database": "H2",
                        "validationQuery": "isValid()"
                    }
                },
                "datasource_1": {
                    "status": "UP",
                    "details": {
                        "database": "Oracle",
                        "validationQuery": "isValid()"
                    }
                },
                "datasource_2": {
                    "status": "UP",
                    "details": {
                        "database": "Oracle",
                        "validationQuery": "isValid()"
                    }
                }
            }
        }

不太完美,因为我现在嵌入的 h2 数据源什么也不做,但至少其他数据源正在工作,我可以再次通过 /info 方法获取它们的状态。

© www.soinside.com 2019 - 2024. All rights reserved.