问题描述:项目为父子多层项目,所有子模块编译通过,运行其中一个子模块时候,报错其他模块的Bean组件注入失败。远程线上环境无问题,本地运行失败。
原因剖析:首先查看了项目依赖的结构,底层模块为common和dao,被其他所有模块依赖,其他模块分为后台系统、远程rsf系统和向前端提供api服务的系统,后台系统独立,api服务系统依赖rsf系统。这次错误是启动后台系统时候报错,检查发现,加载失败的Bean组件属于api服务系统。打开后台系统的Application,查看Application包层级,发现包层级在整个项目最顶层,com.XXX.XXX下。因为SpringBootApplication在启动时,会默认扫描当前包层级下所有的组件加载进入容器,api服务系统的包层级也在com.XXX.XXX之下,所以也会扫描进来,出现问题。
解决方法:最简单的办法,暂时卸载api服务和rsf服务的moudle,项目中没有这些moudle,运行时就不会产生扫描到其他bean的问题。但是这个方法治标不治本。根本解决办法,SpringBoot启动时候可以设置需要扫描的包集合,手动指定需要扫描的包,即可避免这个问题。
@ComponentScan(basePackages={"com.xxx.xx","com.xxx.x"})//扫描指定包下的组件
在添加这个注解之后,启动application时会扫描当前包路径下和ComponentScan添加的包路径,把后台applicaion放到后台层级的包路径下,使用ComponentScan扫描dao层和common层,启动application,问题解决。
总结:因为分布式项目在线上独立部署,所以线上环境不会产生这个问题,但本地调式和线上运行环境不同,需要提前考虑环境产生的问题。