SpringBoot 3启动报错:无法确定合适的DataSource驱动类
SpringBoot 3 应用启动报错:无法配置DataSource
问题背景
原本连接PostgreSQL运行正常的SpringBoot 3应用,重构时将Controller逻辑迁移至新增Service后启动报错,未修改启动类与application.properties配置。
报错信息
APPLICATION FAILED TO START
描述:
无法配置DataSource:未指定'url'属性,且无法配置嵌入式数据源。
原因:无法确定合适的驱动类
操作建议:
请考虑以下情况:
如果需要嵌入式数据库(H2、HSQL或Derby),请将其添加到类路径中。
如果数据库配置需从特定加载,请激活该配置文件(当前无激活的配置文件)。
实际异常栈:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Unsatisfied dependency expressed through method 'dataSourceScriptDatabaseInitializer' 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
已尝试的无效操作
- 在
@SpringBootApplication排除DataSourceAutoConfiguration.class,导致TranslationRepository无法注入到TranslationService - 回滚所有重构操作
- 在
application.properties显式指定PostgreSQL驱动类
相关代码与配置
TranslationApplication.java
package com.projectbluegames.tbd; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class TranslationApplication { public static void main(String[] args) { SpringApplication.run(TranslationApplication.class, args); } }
application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/TBD spring.datasource.username=postgres spring.datasource.password=password spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.datasource.driver-class-name=org.postgresql.Driver
TranslationRepository.java
package com.projectbluegames.tbd.repository; import org.springframework.data.repository.CrudRepository; import com.projectbluegames.tbd.entities.Translation; public interface TranslationRepository extends CrudRepository<Translation, Integer> {}
TranslationController.java
@RestController public class TranslationController { private final ITranslationService translationService; public TranslationController(ITranslationService translationService) { this.translationService = translationService; } @PostMapping("/refresh") private ResponseEntity<String> refreshTranslationCache() { translationService.refreshTranslationCache(); return ResponseEntity.ok("Translation cache reloaded successfully"); } }
ITranslationService.java
package com.projectbluegames.tbd.services; import java.util.List; import com.projectbluegames.tbd.dtos.TranslationDto; public interface ITranslationService { public void refreshTranslationCache(); }
TranslationService.java
package com.projectbluegames.tbd.services; import java.util.HashMap; import java.util.Map; import com.projectbluegames.tbd.entities.Translation; import com.projectbluegames.tbd.repository.TranslationRepository; public class TranslationService implements ITranslationService { private final TranslationRepository translationRepository; private Map<String, Translation> translationCache = new HashMap<String, Translation>(); public TranslationService(TranslationRepository translationRepository) { this.translationRepository = translationRepository; refreshTranslationCache(); } @Override public void refreshTranslationCache() { translationCache.clear(); Iterable<Translation> translations = translationRepository.findAll(); translations.forEach(t -> translationCache.put(t.getLanguage() + "_" + t.getKey(), t)); } }
Translation.java(实体类)
package com.projectbluegames.tbd.entities; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; @Entity @Table(name="translations") public class Translation { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; private String key; private String language; private String value; private Translation() { } public Translation(String key, String language, String value) { this.key = key; this.language = language; this.value = value; } public String getKey() { return key; } public String getLanguage() { return language; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.pb</groupId> <artifactId>core</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <name>tbd</name> <description>Core</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
解决方案
1. 核心问题
TranslationService未添加@Service注解,Spring容器无法识别并管理该Bean。TranslationController依赖注入ITranslationService时找不到实现类,触发容器初始化异常,进而导致DataSource配置逻辑出错。
2. 修复步骤
- 给
TranslationService添加@Service注解:
package com.projectbluegames.tbd.services; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Service; import com.projectbluegames.tbd.entities.Translation; import com.projectbluegames.tbd.repository.TranslationRepository; @Service public class TranslationService implements ITranslationService { private final TranslationRepository translationRepository; private Map<String, Translation> translationCache = new HashMap<String, Translation>(); public TranslationService(TranslationRepository translationRepository) { this.translationRepository = translationRepository; refreshTranslationCache(); } @Override public void refreshTranslationCache() { translationCache.clear(); Iterable<Translation> translations = translationRepository.findAll(); translations.forEach(t -> translationCache.put(t.getLanguage() + "_" + t.getKey(), t)); } }
3. 额外优化
- 将pom.xml中的
packaging从pom改为jar(SpringBoot可运行应用默认打包方式):
<packaging>jar</packaging>
内容的提问来源于stack exchange,提问作者Davey
相关产品推荐
相关产品推荐

