1. 程式人生 > >SpringBoot+Druid報錯Failed to determine a suitable driver class的解決

SpringBoot+Druid報錯Failed to determine a suitable driver class的解決

問題描述

專案中使用了自定義的Spring Listener配置,從網路獲取配置KV,在SpringBoot啟動過程中載入,然後再載入Druid環境。程式啟動時-間歇性報錯(三次啟動可能有一次報錯,其他兩次可以正常啟動):

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

Description:

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

Reason: Failed to
determine a suitable driver class Action: Consider the following: If you want an embedded database (H2, HSQL or Derby), please put it on the classpath. If you have database settings to be loaded from a particular profile you may need to activate it (the profiles de are currently active).

分析

根據日誌顯示,DruidDataSourceWrapper(implements InitializingBean )類載入時,配置資訊還沒有就位。
Druid沒有讀取到資料庫配置,所以引發了上面的報錯。

仔細看程式碼時發現,專案中有兩個類繼承了:SpringBootServletInitializer,其中一個類並沒有載入自定義的那個ApplicationListener。既然有兩個SpringBootServletInitializer,這兩個應該都載入ApplicationListener,獲取只保留一個。

  • 需要確保Druid在讀取配置時,自定義的Listener已經把配置資訊載入好了。

解決

由於專案啟動時,用的是外部Tomcat啟動的方式。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

所以,在繼承自SpringBootServletInitializerServletInitializerconfigure方法中,需要使用application.listeners(),載入自定義的ApplicationListener

部分原始碼:

@Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        // 自定義的ApplicationListener
        application.listeners(buildListener("ServletInitializer"));
        return application.sources(RabiesVaccineApplication.class);
    }

ApplicationListenerInitializingBean前被載入,保證Druid可以讀取到配置資訊,問題解決。

環境

  • spring-boot-starter-parent:2.0.4.RELEASE
  • druid-spring-boot-starter:1.1.10
  • druid:1.1.10
  • jdk:1.8