Spring Boot移除EmbeddedMongo依赖后ServletWebServerFactory缺失问题
问题根源
你遇到的启动失败,本质是Spring启动时尝试加载被你排除的EmbeddedMongoAutoConfiguration.class,但这个类已经被maven插件从最终JAR中移除,导致类找不到异常,进而中断了上下文初始化流程,连Web服务器的自动配置都没完成。
当你在@SpringBootApplication的exclude参数里指定一个类时,Spring会在启动阶段尝试加载该类的Class对象。如果这个类不存在(被打包排除),Spring的上下文初始化逻辑会因为这个潜在的类找不到异常,跳过后续部分自动配置步骤,包括ServletWebServerFactory的创建,最终导致启动报错。
正确解决步骤
1. 移除硬编码的排除配置
首先删掉@SpringBootApplication里的exclude = {EmbeddedMongoAutoConfiguration.class},不要硬编码排除一个可能不存在的类。
2. 用条件化配置控制嵌入式Mongo的启用
通过Profile或类存在性条件,让嵌入式Mongo只在特定环境生效:
方式一:基于Spring Profile(推荐,环境区分更清晰)
创建一个单独的配置类,仅在开发/测试Profile下启用嵌入式Mongo:
@Configuration @Profile({"dev", "test"}) // 指定要启用的环境Profile @Import(EmbeddedMongoAutoConfiguration.class) public class EmbeddedMongoEnvConfig { // 可添加自定义Mongo配置,比如端口、存储路径等 }
方式二:基于类存在性自动判断
如果不想依赖Profile,用@ConditionalOnClass自动检测类是否存在,仅在类存在时加载配置:
@Configuration @ConditionalOnClass(EmbeddedMongoAutoConfiguration.class) @Import(EmbeddedMongoAutoConfiguration.class) public class EmbeddedMongoAutoConfig { }
3. 调整Maven依赖Scope,避免不必要的打包
把flapdoodle的依赖设为test scope(仅测试时生效),或者用Maven Profile控制不同环境的依赖引入:
基础配置(仅测试环境引入)
<dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo.spring30x</artifactId> <scope>test</scope> </dependency>
多环境Profile配置(支持IDE开发环境)
如果需要在IDE的开发环境(非test)也使用嵌入式Mongo,添加Maven Profile:
<profiles> <profile> <id>dev</id> <activation> <activeByDefault>false</activeByDefault> </activation> <dependencies> <dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo.spring30x</artifactId> <scope>compile</scope> </dependency> </dependencies> </profile> <profile> <id>prod</id> <activation> <activeByDefault>true</activeByDefault> </activation> <!-- 生产环境自动跳过flapdoodle依赖 --> </profile> </profiles>
4. 移除Maven插件的排除配置
现在不需要再用spring-boot-maven-plugin的excludeGroupIds了,因为依赖已经通过Scope或Profile控制,不会被打包到生产JAR中。
验证效果
- 测试/开发环境:启动时会加载嵌入式Mongo的配置,正常运行。
- 生产环境:JAR中没有flapdoodle相关类,Spring也不会尝试加载不存在的配置类,Web服务器的自动配置正常执行,应用启动成功。
内容的提问来源于stack exchange,提问作者Garret Wilson

