内容提要
文章讲解Spring Boot中@Autowired找不到Bean的常见错误。@SpringBootApplication包含@ComponentScan,默认扫描启动类所在包及子包。若将Application移到子目录,未包含Controller所在包,Controller就不会被识别为Bean,导致404。解决办法是把Application放在项目最外层,或使用@ComponentScans指定扫描范围。
延伸解读
包结构变动为何导致Bean失效
文章指出,@SpringBootApplication 包含 @ComponentScan,默认扫描启动类所在包及子包。若将 Application 移到子目录,其所在包不再包含 Controller 所在包,Controller 便不会被识别为 Bean,访问时返回 404。这提醒开发者:调整包结构时需留意启动类位置对组件扫描范围的影响。
默认扫描规则与常见修复方式
当 @ComponentScan 的 basePackages 为空时,扫描范围是声明该注解的类所在的包。因此,将 Application 放在项目最外层目录,即可覆盖其子目录下的组件。文章也提到,可以使用 @ComponentScans 显式指定扫描范围来修复问题。两种方式各有适用场景,前者依赖约定,后者更灵活。
约定优于配置的潜在陷阱
文章强调 Spring 建立在许多约定俗成的规则之上,这些约定未必是开发者所熟悉的。一旦遇到问题,可能令人抓狂。本例中仅移动包结构就导致 Web 应用失效,说明理解默认扫描机制有助于快速定位类似“找不到 Bean”的错误,避免在代码逻辑上做无用排查。
Q&A
Spring Boot 启动时默认扫描哪些包?
默认扫描启动类(Application)所在的包及其子包。因为 @SpringBootApplication 包含 @ComponentScan,且未指定 basePackages,所以扫描范围是启动类所在包。
为什么把 Application 类移到子目录后,Controller 就找不到了?
因为 @ComponentScan 默认扫描启动类所在包及子包。如果 Application 被移到子目录(如 com.brmayi.concise.startup),而 Controller 在父包(com.brmayi.concise),则 Controller 不在扫描范围内,不会被注册为 Bean,导致 404。
如何解决 Spring Boot 中 @Autowired 找不到 Bean 的问题?
有两种方法:1. 将 Application 类放在项目最外层目录,确保扫描范围覆盖所有组件;2. 使用 @ComponentScans 注解显式指定扫描的包。
@SpringBootApplication 注解包含哪些功能?
@SpringBootApplication 是一个组合注解,包含 @EnableAutoConfiguration 和 @ComponentScan(带有排除过滤器),用于启用自动配置和组件扫描。
为什么通常建议把 Application 类放在项目最外层目录?
因为 @ComponentScan 默认扫描启动类所在包及子包。将 Application 放在最外层目录可以确保扫描到所有子包中的组件(如 Controller、Service 等),避免 Bean 找不到的问题。
访问接口时出现 404 错误,可能是什么原因?
可能是 Controller 没有被扫描到,即 Controller 不在 @ComponentScan 的扫描范围内。例如,Application 类被移动到子目录,导致 Controller 所在包不在扫描范围,Controller 未被注册为 Bean,从而 404。