返回
在Spring JavaConfig中配置类路径扫描时,必须格外留意的是根路径包与子模块扫描路径包重复的问题
后端
2024-01-29 00:30:04
前言
为了简化开发,我们部门经常会封装一些通用的类库给业务研发使用,因为业务方的根包路径很经常和我们部门项目的根包是不一样的,因此我们会让业务方在使用我们封装的包时,扫描一下我们的根包,形如下:
@SpringBootApplication
@ComponentScan({"com.xxx.xxx", "com.xxx.yyy"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
这样一来,业务方就可以直接使用我们封装的类库了,而无需关心类库的具体实现细节。
踩坑经历
然而,在一次使用Spring JavaConfig配置类路径扫描时,我们遇到了一个坑。在我们的项目中,我们使用到了两个子模块,这两个子模块分别位于com.xxx.xxx
和com.xxx.yyy
包下。在我们的根包com.xxx
下,我们有一个Application
类,该类使用了@SpringBootApplication
和@ComponentScan
注解。我们希望@ComponentScan
注解能够扫描com.xxx.xxx
和com.xxx.yyy
这两个子模块。
@SpringBootApplication
@ComponentScan({"com.xxx.xxx", "com.xxx.yyy"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
但是,当我们运行项目时,却遇到了一个循环依赖的错误。经过排查,我们发现,这是因为com.xxx.xxx
和com.xxx.yyy
这两个子模块都扫描到了com.xxx
这个根包。这样一来,com.xxx
这个根包又扫描到了com.xxx.xxx
和com.xxx.yyy
这两个子模块,从而形成了一个循环依赖。
解决办法
为了解决这个问题,我们可以将根路径包从子模块扫描路径包中排除,或者将子模块扫描路径包从根路径包中排除。
方法一:将根路径包从子模块扫描路径包中排除
@SpringBootApplication
@ComponentScan({"com.xxx.xxx", "com.xxx.yyy"}, excludeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.xxx")})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
方法二:将子模块扫描路径包从根路径包中排除
@SpringBootApplication
@ComponentScan({"com.xxx.xxx"})
@ComponentScan({"com.xxx.yyy"}, excludeFilters = {@ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.xxx")})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
总结
在Spring JavaConfig中配置类路径扫描时,必须格外留意的是根路径包与子模块扫描路径包重复的问题。如果根路径包和子模块扫描路径包重复,则会导致循环依赖和错误。为了解决这个问题,可以将根路径包从子模块扫描路径包中排除,或者将子模块扫描路径包从根路径包中排除。