[特殊字符] Spring Cloud 微服务项目中 common 模块依赖导致网关启动失败的排查与解决
在微服务项目中,common 模块常被用于封装通用配置,但若其中引入了数据库相关依赖(如 MyBatis Plus),会被传递到如网关 gateway 等不需要数据库的模块,导致启动报错:“Failed to determine a suitable driver class”。可通过将依赖设置为 <scope>provided>、为配置类添加 @ConditionalOnClass 注解或拆分模
在进行微服务开发时,我们通常会抽取一个 common
公共模块,封装一些通用配置类、工具类、拦截器、常用组件依赖等,供多个微服务共享使用。
但近期在实际开发中,出现了一个典型问题:在 Gateway 网关模块中引入 common
后启动报错,提示数据库驱动未配置,而网关模块根本不涉及数据库操作!
本文将还原这一问题的场景、原因分析、解决过程与最佳实践建议。
🧩 问题现象
-
网关服务
gateway
模块中引入了如下依赖:
<dependency>
<groupId>com.zicai</groupId>
<artifactId>partner-common</artifactId>
<version>1.0.0</version>
</dependency>
-
启动时报如下错误:
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
而此时你明明并未在网关模块中配置数据源或引用数据库类库!
🧾 排查过程
🔍 1. 查看 common 模块中的依赖
common
模块中包含如下依赖:
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
这些数据库相关依赖 是以默认 scope=compile 引入的,因此会被传递给所有引用 common
的模块,包括 gateway。
🔍 2. common 中含有数据库配置类
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
由于该配置类是 @Configuration
且无条件加载的,Spring Boot 启动时尝试初始化它,导致触发数据库依赖初始化,最终报错找不到驱动类。
✅ 解决方案
✅ 方法一:将数据库相关依赖设置为 <scope>provided
这是最推荐的做法之一。
<!-- common 模块中 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<scope>provided</scope>
</dependency>
作用:只在 common
编译期生效,不会传递给引用它的其他模块(如 gateway),避免被网关加载。
✔️ 注意:此方式下,业务模块需要自行引入所需依赖,如
user-service
模块需要单独加上数据库依赖。
✅ 方法二:为配置类添加 @ConditionalOnClass
可用于避免无数据库模块误加载数据库配置类:
@Configuration
@ConditionalOnClass(MybatisPlusInterceptor.class)
public class MybatisPlusConfig {
...
}
作用: 若项目中不存在 MybatisPlusInterceptor
类(即未引入相关依赖),则该配置类不会生效或被加载。
✅ 方法三:模块拆分更清晰
将 common
拆成多个模块:
-
common-core
:通用工具类、常量类、枚举类等; -
common-db
:MyBatis Plus、数据库配置; -
common-web
:拦截器、WebMvcConfigurer
等;
然后:
-
网关只依赖
common-core
-
业务模块依赖
common-db
,common-web
✨ 优点是依赖明确,职责清晰;缺点是模块稍复杂,适合大型项目。
💡 总结建议
方法 | 场景 | 优点 | 注意 |
---|---|---|---|
✅ <scope>provided |
通用配置但运行时不需要 | 不传递依赖,编译有效 | 引用方需手动声明依赖 |
✅ @ConditionalOnClass |
部分模块才需配置 | 自动适配,控制灵活 | 忽略类可能导致误判 |
✅ 拆模块 | 多服务多功能项目 | 高内聚低耦合 | 工程结构更复杂 |
❌ 直接 compile | 小项目可接受 | 简单 | 易出错,不推荐用于公共模块 |
📌 小贴士
如果你在 gateway 模块中看到以下关键词异常:
-
Failed to determine a suitable driver class
-
No embedded datasource could be configured
-
BeanCreationException: dataSource
那么十有八九是你引入了带有数据库依赖的模块或配置类,应优先检查 common
或其他基础模块!
📚 参考
如果你也在做分布式微服务项目,希望这篇文章能帮你少踩一些依赖地雷。觉得有帮助的话欢迎点赞、评论、收藏哦!
更多推荐
所有评论(0)