StackTraces
Spring Boot已驗證

Spring Boot 報 Failed to configure a DataSource

@debug_master32 天前更新閱讀 6 min00

報 Failed to configure a DataSource 不是數據庫連不上,而是啟動階段壓根沒拿到 spring.datasource.url。只要 classpath 上有 JDBC/JPA 依賴,DataSourceAutoConfiguration 就會強制裝配數據源,找不到 url 又沒有 H2 這類內嵌庫,直接拒絕啟動。要麼把連接屬性補齊,要麼把自動設定關掉。

Issue & Env(案發現場與環境)

  • 業務場景:新建 Spring Boot 項目,pom 里加了 spring-boot-starter-data-jpa(或 spring-boot-starter-jdbc),還沒寫任何數據庫連接設定就啟動。
  • 環境:Spring Boot 2.x / 3.x 均受影響,這是自動設定的設計行為,與具體版本無關。issue #15758 報告用的是 2.0.5.RELEASE,但 3.x 的報錯形態一致。

StackTrace(堆疊日誌)

啟動即掛,控制台報錯把兩條建議路徑都寫明瞭:

***************************
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

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 configured by Spring Boot, perhaps you forgot to specify the database connection details?

完整的 Java 例外鏈:

org.springframework.beans.factory.BeanCreationException: 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
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:652)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:443)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:736)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1341)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:612)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:962)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:930)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:596)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1307)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1296)
	at com.example.demo.Application.main(Application.java:12)
Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceDriverNotFoundException: Failed to determine a suitable driver class
	at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:213)
	at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.initializeDataSourceBuilder(DataSourceProperties.java:188)
	at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:60)
	at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari.dataSource(DataSourceConfiguration.java:44)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:159)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:648)
	... 17 more

Reproduce(復現程式碼)

pom 裡引入 JPA starter,不帶運行時數據庫依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

啟動類照常:

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

application.properties 裡什麼都不寫,直接 mvn spring-boot:run,啟動就報上面的錯誤。

Root Cause(根因分析)

Spring Boot 的自動設定是「看依賴下菜」:DataSourceAutoConfiguration 用 @ConditionalOnClass 監聽 classpath,一旦發現 DataSource 和 EmbeddedDatabaseType(由 JDBC 驅動或 starter 引入)就在,就認為「這個應用要用數據庫」,開始裝配 DataSource Bean。

裝配時 DataSourceProperties 需要至少一個 spring.datasource.url 來定位數據庫;沒有 url,它就退而求其次,去 classpath 上找內嵌庫(H2、HSQL、Derby)的驅動。兩條路都不通時,determineDriverClassName() 拋例外,整個應用上下文拒絕刷新。

所以這個坑的觸發條件很明確:JPA/JDBC 依賴在 classpath 上,但既沒配 url,也沒放內嵌庫。issue #15758 的提問者就踩在這——pom 裡既有 spring-boot-starter-data-jpa 又有 mysql-connector-java,卻忘了寫 spring.datasource.*。

The Fix(解決方案)

正解:補上連接屬性

給外部數據庫補全地址、賬號、驅動即可:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/my_db
    username: user1
    password: pass
    driver-class-name: com.mysql.cj.jdbc.Driver

用 application.properties 同理:

spring.datasource.url=jdbc:mysql://localhost:3306/my_db
spring.datasource.username=user1
spring.datasource.password=pass
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

測試/演示場景:放一個內嵌庫

只想跑起來、不接真庫,把 H2 加進 classpath,Spring Boot 會自動用內嵌庫配出可用的 DataSource:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

壓根不用數據庫:關掉自動設定

應用其實不碰關係庫(比如只用 Redis、Mongo、ES),是父 POM 裡殘留了 JPA 依賴,那就別讓 DataSourceAutoConfiguration 生效:

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class Application {}

或在設定裡指定:

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

排除後 Spring Boot 不再裝配數據源,應用正常啟動。代價是自己保證沒有程式碼去注入 DataSource、JdbcTemplate 或 EntityManager,否則運行時才會報「找不到 Bean」。

References(參考來源)

最後更新於 2026-09-09

這篇幫到你了嗎?

剛解決了一個棘手的報錯?花兩分鐘記錄下來,幫助下一個遇到同樣問題的開發者。

貢獻一條解法