驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
一款非常优秀的包扫描库推荐
/  

一款非常优秀的包扫描库推荐

开篇

最近有个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-INFwar 包的是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

骐骥一跃,不能十步。驽马十驾,功在不舍。