一、误解
一开始我一直以为spring boot默认的包扫描范围是启动类的同级目录和子目录下的Bean
。其实正真是与启动类在同个包以及子包下的Bean
。
我一直误解了包的概念,包并不是只文件夹(文件路径)。
只扫描这个文件夹下的所有类。
上面的理解是完全错误的,也就是你误解了java中包的概念,包不等于文件夹。。。
二、正确的理解
在同一个项目中,一般会有很多模块。如下:
mian模块中有spring boot的启动类。如果想要让main模块扫描到并使用commom模块中的Bean应该做?
我们已经知道spring boot的默认包扫描规则是:启动类在同个包以及子包下的Bean
。因此我们只需要将main模块的包命名,用在commom模块中,并保持在同包或子包下即可。如下:
在main和commom两个模块中,main 的包名为:com.lihua
,commom 的包名为:com.lihua.test
。符合同包或者子包的规则。因此commom下的bean能直接被扫描到。
例子:
启动类所在包 | 其他模块的Bean所在包 | 能否扫描到Bean |
---|---|---|
com.lihua | com.lihua.test | 能 |
com.lihua | com.lihua1.test | 不能 |
三、不同包也能扫描到Bean的方法
- 在启动类添加包扫描。
@ComponentScan(value = {"com.lihua1.**","com.lihua.**"})
注意:手动配置后,默认的就失效了,所以要加上原来的包路径(本包路径)。 - 通过配置
META-INF/spring.factories
文件。spring boot2.7以前
- 通过配置
/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件 。spring boot2.7以后
一般来说,包路径等于项目、公司的域名的逆写。比如项目域名:lihua.com
,包路径就为:com.lihua
。因此导入的三方maven依赖(spring boot 提供的starter,自己的starter,三方的starter
)时,starter中的Bean如何扫描呢?总不能一个个在@ComponentScan
注解加上吧。因此spring boot 通过使用上面 2,3
的方式实现包扫描。