Spring Boot多模块项目@Autowired注入失败,提示Bean找不到
问题排查与解决方案
核心问题分析
- Bean扫描范围不足:默认情况下,
@SpringBootApplication只会扫描其所在包(com.xx.campaign_api)及其子包下的组件。你的服务类位于com.xxx.campaign.common包,不在默认扫描范围内,导致Spring无法将MyServiceImpl识别为Bean。 - 错误的
@SpringBootApplication使用:你把@SpringBootApplication注解加到了控制器类上,覆盖了原主启动类的配置,Spring无法初始化Web服务器相关Bean,从而抛出ServletWebServerFactory找不到的错误。
分步解决
1. 修正主启动类的扫描范围
保留原主启动类CampaignApiApplication,修改注解扩大扫描范围,覆盖服务类所在包:
package com.xx.campaign_api; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = {"com.xx.campaign_api", "com.xxx.campaign.common"}) public class CampaignApiApplication { public static void main(String[] args) { SpringApplication.run(CampaignApiApplication.class, args); } }
若服务包前缀和控制器一致(如都是
com.xx),可简化为scanBasePackages = "com.xx",确保覆盖所有需要扫描的组件包。
2. 移除控制器类上的@SpringBootApplication注解
控制器仅保留@RestController注解即可:
package com.xx.campaign_api.controller; import com.xx.campaign.common.service.MyService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class MyController { private final MyService testService; // 构造器注入推荐用final修饰成员变量,保证不可变 @Autowired public MyController(MyService testService) { this.testService = testService; } @GetMapping("/test") public String test() { return testService.test(); } }
3. 检查包名一致性(关键细节)
注意到代码中服务类的包是com.xxx.campaign.common,但控制器导入的是com.xx.campaign.common,存在包名多一个x的不一致问题,请确认实际包名统一,避免编译或运行时类找不到的错误。
4. 验证依赖配置
确保API模块对common模块的依赖版本与父pom一致:
<dependency> <groupId>org.springframework</groupId> <!-- 需与父pom的groupId保持一致 --> <artifactId>campaign-common</artifactId> <version>0.1.0</version> <scope>compile</scope> </dependency>
验证启动
完成以上修改后,重新启动CampaignApiApplication,Spring会正确扫描到MyServiceImpl并注册为Bean,控制器的构造器注入即可正常工作。
内容的提问来源于stack exchange,提问作者John Little
相关产品推荐
相关产品推荐

