最近有个SpringBoot
项目,需要扫描指定包下带有带有指定注解的类,最开始使用的是hutool
下的 ClassScaner.scanPackageByAnnotation
这个方法进行扫描。
在前期开发阶段工作正常,但是最近在中期部署的时候,将 SpringBoot
项目打包成 jar
后在服务器运行的时候,直接报出了空指针异常,经过查看记录,代码没有在指定包下找到任何一个 class
。
为了解决这个问题我尝试了如下方法:
JDK
本来是 OpenJDK
,更换成了 SunJDK
,无法解决!Guava
提供的 ClassPath.from
,无法解决!war
包后,部署到 tomcat
后运行,成功解决!经过上述测试后发现,只有将项目打包为war 后在 Tomcat下运行才能正常扫描。这下我的心都凉了,因为如果一个SpringBoot
项目还必打包为传统的 war 然后部署,那么SpringBoot
的优势会少很多。
为什么 war
包可以正常运行,jar
包不行了?
我对比了2者的不同,如下图所示:
发现 jar
包下的BOOT-INF
,war
包的是WEB-INF
,难道是这个原因?
今天询问各个大神,暂时都没得到很好的答案,所以尝试着借助 google
来进行解决。
很幸运的发现 github
上一个项目的 issue
有个讨论问题的帖子,通过这个帖子我发现了这个非常不错的项目fast-classpath-scanner
。
这个项目提供了一种非常高效快速且兼容性好的包扫描机制,具体介绍大家可以查阅相关的 说明。
地址:https://github.com/lukehutch/fast-classpath-scanner
API 使用说明在 wiki中写的很清楚,我通过如下代码解决打包为 jar 后扫描不到的问题
引入pom.xml
<dependency>
<groupId>io.github.lukehutch</groupId>
<artifactId>fast-classpath-scanner</artifactId>
<version>2.21</version>
</dependency>
代码如下:
Set<Class<?>> restClasses = new HashSet<>();
new FastClasspathScanner(basePackage).matchClassesWithAnnotation(MyAnotation.class, restClasses::add).scan();
这个库声称不是通过反射来进行查找的,同时支持字段查找、方法信息查找等。
更多的功能,请自行探索,其wiki
地址为:https://github.com/lukehutch/fast-classpath-scanner/wiki