有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Spring引导升级后,java无法实例化自定义库的数据源

我在具有自动配置的库中定义了自定义数据源:

@Configuration
@ConditionalOnProperty(
        name = ["spring.datasource.type"],
        havingValue = "org.example.datasource.connector.RoutingDataSource",
        matchIfMissing = true
)
@EnableConfigurationProperties(RoutingDataSourceConfig::class)
@Import(value = [
        RoutingDataSourceBeanPostProcessor::class,
        WriteRouteInterceptor::class
])
@EnableAspectJAutoProxy
class RoutingDataSourceAutoConfiguration{
        @Bean
        @ConditionalOnMissingBean(DataSource::class)
        fun dataSource(routingDataSourceConfig: RoutingDataSourceConfig): RoutingDataSource {
                return RoutingDataSource().also {
                        it.initDataSources(routingDataSourceConfig)
                }
        }

        @Bean
        @ConditionalOnBean(RoutingDataSource::class)
        fun writeDataSource(routingDataSource: RoutingDataSource) =
                routingDataSource.getWriteDataSource()

}

使用spring工厂文件:

# Auto Configure
org.springframework.boot.autoconfigure.AutoConfigureBefore=\
  org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  org.example.datasource.connector.RoutingDataSourceAutoConfiguration

数据源配置如下

spring:
    datasource:
        url: jdbc:postgresql://${POSTGRESQL_HOSTPORT}/chords?targetServerType=master&reWriteBatchedInserts=true
        routing:
            write:
                jdbcUrl: jdbc:postgresql://${POSTGRESQL_HOSTPORT}/chords?targetServerType=master&reWriteBatchedInserts=true
                username: ${POSTGRESQL_USERNAME}
                password: ${POSTGRESQL_PASSWORD}
                schema: chords
            read:
                jdbcUrl: jdbc:postgresql://${POSTGRESQL_HOSTPORT}/chords?loadBalanceHosts=true
                username: ${POSTGRESQL_USERNAME}
                password: ${POSTGRESQL_PASSWORD}
                schema: chords
                readOnly: true
        type: org.example.datasource.connector.RoutingDataSource

它在SpringBoot2.4.2上运行良好。但是,当我将其升级到2.5.2时,我的应用程序没有启动,因为它无法创建dataSourcebean并抛出异常

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.flywaydb.core.Flyway]: Factory method 'flyway' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Generic.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.jdbc.UnsupportedDataSourcePropertyException: Unable to find suitable method for url
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
    ... 21 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Generic.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.jdbc.UnsupportedDataSourcePropertyException: Unable to find suitable method for url
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.getIfUnique(DefaultListableBeanFactory.java:2063)
    at org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration$FlywayConfiguration.flyway(FlywayAutoConfiguration.java:117)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 22 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.jdbc.UnsupportedDataSourcePropertyException: Unable to find suitable method for url
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
    ... 40 common frames omitted
Caused by: org.springframework.boot.jdbc.UnsupportedDataSourcePropertyException: Unable to find suitable method for url
    at org.springframework.boot.jdbc.UnsupportedDataSourcePropertyException.throwIf(UnsupportedDataSourcePropertyException.java:36)
    at org.springframework.boot.jdbc.DataSourceBuilder$ReflectionDataSourceProperties.getMethod(DataSourceBuilder.java:561)
    at org.springframework.boot.jdbc.DataSourceBuilder$ReflectionDataSourceProperties.set(DataSourceBuilder.java:543)
    at org.springframework.boot.jdbc.DataSourceBuilder.build(DataSourceBuilder.java:181)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Generic.dataSource(DataSourceConfiguration.java:150)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 41 common frames omitted

我怎样才能解决这个问题


共 (1) 个答案

  1. # 1 楼答案

    在默认情况下,不会指定自动配置类的求值顺序,并且微小的更改(可能使HashMap重新排序的更改)可能会导致此类失败。您需要指示Boot按特定顺序评估类中的条件:

    @AutoConfigureBefore(DataSourceAutoConfiguration::class)

    (我想这就是你的意思,你自己定义一个DataSourcebean,但是你可能需要@AutoConfigureAfter。)