手记

java如何扫描本项目下的所有类

最近在写一个依赖注入的小demo,碰到这么样的一个问题:

要把本项目下所有被@Component修饰的所有类注入到容器当中。

思路很简单,通过文件枚举的方式扫描出本项目的所有类文件,再对文件名进行一些小处理,就能得到本项目的所有类。

public static void scanAllClasses() {
       String url = getClassPath();
       List<String> classes = getClassesList(url);
       // 遍历classes,如果发现@Component就注入到容器中
       scanComponent2Container(classes);

   }

其中,getClassPath这个方法的实现如下:

private static String getClassPath() {
       String url = URLDecoder.decode(Context.class.getResource("/").getPath(), Charset.defaultCharset());
       if (url.startsWith("/")) {
           url = url.replaceFirst("/", "");
       }
       url = url.replaceAll("/", "\\\\");
       return url;
   }

就是通过类来取出这个类所在文件的绝对路径,并进行一些文本处理。

而getClassesList则是根据传入的类路径,通过递归进行文件枚举:

private static List<String> getClassesList(String url) {
       File file = new File(url);
       List<String> classes = getAllClass(file);
       for (int i = 0; i < classes.size(); i++) {
           classes.set(i, classes.get(i).replace(url, "").replace(".class", "").replace("\\", "."));
       }
       return classes;
   }

递归函数:

private static List<String> getAllClass(File file) {
       List<String> ret = new ArrayList<>();
       if (file.isDirectory()) {
           File[] list = file.listFiles();
           for (var i : list) {
               var j = getAllClass(i);
               ret.addAll(j);
           }
       } else {

           ret.add(file.getAbsolutePath());
       }
       return ret;
}

基本原理就是判断file是否为目录,如果是,继续递归,否则如果文件是class文件,加入到list,返回。

那这样,就能得到本项目下的所有类。

值得注意的是,这种方式不适用jar执行包,因为如果java直接执行jar包的话,第一步得到的类路径就是jar包的地址。

所以如果最终运行的是jar包的话,必须通过jar输入流进行读取。


0人推荐
随时随地看视频
慕课网APP