在现在好多应用场景中,我们需要得到某个包名下面所有的类, 包括我们自己在src里写的java类和一些第三方提供的jar包里的类,那么怎么来实现呢?

今天带大家来完成这件事。

先分享代码

1.这个类是一个抽象类,对类的处理交给用户,所以就有了dealClass的抽象方法。

  1 package com.mec.packscanner.core;
  2
  3 import java.io.File;
  4 import java.io.FileFilter;
  5 import java.io.IOException;
  6 import java.net.JarURLConnection;
  7 import java.net.URISyntaxException;
  8 import java.net.URL;
  9 import java.util.Enumeration;
 10 import java.util.jar.JarEntry;
 11 import java.util.jar.JarFile;
 12
 13 public abstract class PackageScanner {
 14     public PackageScanner() {}
 15
 16     public abstract void dealClass(Class<?> klass);
 17
 18     //扫描一般的包。
 19     private void scanPackage(String packageName,File currentfile) {
 20         File[] filelist = currentfile.listFiles(new FileFilter() {
 21             //FileFilter是文件过滤器,源代码只写了一个accapt的抽象方法。
 22             @Override
 23             public boolean accept(File pathName) {
 24                 if(pathName.isDirectory()) {    //判断是否是目录
 25                     return true;
 26                 }
 27                 return pathName.getName().endsWith(".class");
 28             }
 29         });
 30
 31         for(File file:filelist) {
 32             if(file.isDirectory()) {
 33                 scanPackage(packageName + "." + file.getName(),file);
 34             }else {
 35                 String fileName = file.getName().replace(".class", "");
 36                 String className = packageName + "." + fileName;
 37                 try {
 38                     Class<?> klass = Class.forName(className);//取出所有的类
 39                     if(klass.isAnnotation() //不扫描注解类、枚举类、接口和八大基本类型。
 40                             ||klass.isEnum()
 41                             ||klass.isInterface()
 42                             ||klass.isPrimitive()) {
 43                         continue;
 44                     }
 45                     dealClass(klass);
 46                 } catch (ClassNotFoundException e) {
 47                     e.printStackTrace();
 48                 }
 49             }
 50         }
 51     }
 52
 53     //扫描jar包方法。
 54     private void scanPackage(URL url) throws IOException {
 55         JarURLConnection urlConnection = (JarURLConnection) url.openConnection();
 56         JarFile jarfile = urlConnection.getJarFile();
 57         Enumeration<JarEntry> jarEntries = jarfile.entries();
 58         while(jarEntries.hasMoreElements()) {
 59             JarEntry jarEntry = jarEntries.nextElement();
 60             String jarName = jarEntry.getName();
 61             if(!jarName.endsWith(".class")) {
 62                 continue;
 63             }
 64             String className = jarName.replace(".class", "").replaceAll("/", ".");
 65
 66             try {
 67                 Class<?> klass = Class.forName(className);
 68                 if (klass.isAnnotation()
 69                         || klass.isInterface()
 70                         || klass.isEnum()
 71                         || klass.isPrimitive()) {
 72                     continue;
 73                 }
 74                 dealClass(klass);
 75             } catch (ClassNotFoundException e) {
 76                 e.printStackTrace();
 77             }
 78         }
 79     }
 80
 81     //用类名扫描
 82     public void packageScan(Class<?> klass) {
 83         packageScan(klass.getPackage().getName());
 84     }
 85
 86     //用包名进行扫描
 87     public void packageScan(String packageName) {
 88         String packOpperPath = packageName.replace(".","/");
 89
 90         //线程上下文类加载器得到当前的classpath的绝对路径.(动态加载资源)
 91         ClassLoader classloader = Thread.currentThread().getContextClassLoader();
 92         try {
 93             //(Thread.currentThread().getContextClassLoader().getResource(""))
 94             //(来得到当前的classpath的绝对路径的URI表示法。)
 95             Enumeration<URL> resources = classloader.getResources(packOpperPath);
 96             while(resources.hasMoreElements()) {
 97                 //先获得本类的所在位置
 98                 URL url = resources.nextElement();
 99
100                 //url.getProtocol()是获取URL的HTTP协议。
101                 if(url.getProtocol().equals("jar")) {
102                 //判断是不是jar包
103                     scanPackage(url);
104                 }else {
105                     //此方法不会自动将链接中的非法字符转义。
106                     //而在File转化成URI的时候,会将链接中的特殊字符如#或!等字符进行编码。
107                     File file = new File(url.toURI());
108                     if(!file.exists()) {
109                         continue;
110                     }
111                     scanPackage(packageName,file);
112                 }
113             }
114         } catch (IOException e) {
115             e.printStackTrace();
116         } catch (URISyntaxException e) {
117             e.printStackTrace();
118         }
119     }
120 }

这个是抽象类,对于扫描,我们只提供扫描的工具,而定义抽象方法是往外接,通过使用者的使用来决定用类名还是包名。

对于jar包的扫描,可以进JarURLConnection类和JarFile类的源码中可以理解。

2.定义测试类,它是扫描jar包的:

 1 package com.mec.packscanner.test;
 2
 3 import com.mec.packscanner.core.PackageScanner;
 4
 5 public class Test {
 6
 7     public static void main(String[] args) {
 8         new PackageScanner() {
 9
10             @Override
11             public void dealClass(Class<?> klass) {
12                 System.out.println(klass.getName());
13
14             }
15         }.packageScan("com.mec.xml_view.core");;
16     }
17
18 }

结果:

从结果我们可以看出把jar包中的每一个class都输出了,匿名内部类都被扫描出来了。

我们来看看普通包的结果吧:

 1 package com.mec.packscanner.test;
 2
 3 import com.mec.packscanner.core.PackageScanner;
 4
 5 public class Test {
 6
 7     public static void main(String[] args) {
 8         new PackageScanner() {
 9
10             @Override
11             public void dealClass(Class<?> klass) {
12                 System.out.println(klass.getName());
13
14             }
15         }.packageScan("com.mec.server_client.core");;
16     }
17
18 }

对普通的包也是,这个例子除了接口,其他的都被扫描出来了。

若有漏洞,请指正!感谢您的阅读。

转载于:https://www.cnblogs.com/youdiaodaxue16/p/9813087.html

Java中的包扫描(工具)相关推荐

  1. java.lang包有哪些类_Java中Lang包的工具类有哪些

    Java中Lang包的工具类有哪些 发布时间:2020-12-08 16:15:36 来源:亿速云 阅读:76 作者:Leah 今天就跟大家聊聊有关Java中Lang包的工具类有哪些,可能很多人都不太 ...

  2. jar包扫描工具: gamma

    1. 简介 本项目是一个jar包扫描工具,可以支持插件化订制不同的扫描逻辑 支持以下功能: 插件化订制扫描逻辑,让扩展更加容易 将扫描到的文件加载到jvm中以class的形式返回给处理插件,让扫描逻辑 ...

  3. golang中的包管理工具——govendor和godep简单学习

    为什么用vendor目录 依赖问题 我们知道,一个工程稍大一点,通常会依赖各种各样的包.而Go使用统一的GOPATH管理依赖包,且每个包仅保留一个版本.而不同的依赖包由各自的版本工具独立管理,所以当所 ...

  4. ssm项目配置文件中的包扫描bean,排除特定bean的扫描

    ssm项目配置文件中的包扫描bean springMVC.xml: 自动扫描controller包下的所有类,使其认为spring mvc的控制器 <!-- 自动扫描controller包下的所 ...

  5. java中常用的加密工具

    java中常用的加密工具 1. md5加密工具类 public class MD5Utils {private static final String hexDigIts[] = {"0&q ...

  6. Java中的包(package)详情解释

    一.Java 包(package) 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间. 包的作用 1.把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2.如同文件夹一 ...

  7. Java中jar包怎么使用_java中jar包的使用方法

    java中jar包的使用方法 发布时间:2020-06-23 11:08:05 来源:亿速云 阅读:162 作者:Leah 这篇文章将为大家详细讲解有关java中jar包的使用方法,小编觉得挺实用的, ...

  8. java中常用的日期工具类

    java中常用的日期工具类 日期相关的类: package net.yto.ofclacct.core.util;import java.text.ParseException; import jav ...

  9. 【Java学习笔记四】Java中的包

    包的声明和引入:在Java语言系统中,Java编译器为每一个类生成一个字节码文件(.class),为了对类文件进行分层和按用途分类管理,同时也为了解决相同类名的文件冲突的问题,Java提供了包机制来管 ...

最新文章

  1. undistortPoints()函数用法总结
  2. JS组件系列——BootstrapTable 行内编辑解决方案:x-editable
  3. 十 ubus安装编译
  4. JAVA 判断其是否为合法标识符
  5. 遍历flex和flash对象的属性和方法
  6. 月薪3K与月薪3万的程序员,距离是怎么拉开的?
  7. HTML label控件
  8. 的电路接法_基本震荡电路知多少,汇总几种震荡电路的接法!
  9. iOS开发之UI控件阴影效果
  10. [Python] 当猎头遇上 Guido van Rossum
  11. Node.js:使用blueimp-md5进行MD5加密
  12. 《ERP原理》期末复习——第一章 初识ERP(企业资源计划)
  13. ArcGIS Pro脚本工具(10)——从图层生成.stylx样式符号
  14. cobar mysql_cobar mysql 高可用
  15. Guava Joiner
  16. 二十多年了,安全套市场还只有杜蕾斯、冈本、杰士邦
  17. 阿里云搭建Tomcat+Jdk+Mysql(阿里云系统CentOs)特完整
  18. 我叫mt4最新服务器,我叫mt4新区开服表 最新新区开服时间汇总分享[多图]
  19. 帝国CMS(EmpireCMS) v7.5配置文件写入漏洞分析
  20. R 回归分析 多元线性回归

热门文章

  1. WebStorm 是什么软件
  2. 网恋奔现发现对方长得很好看是什么样的体验?
  3. “华为”和“荣耀”手机有什么区别?
  4. 流量少怎么办?先考虑下面四项
  5. 互联网35岁中年危机的来龙去脉
  6. go使用mongodb
  7. Go语言并发模型:使用 context
  8. Qt——P25 QListWidget控件
  9. JDBC(实现增删改查的通用操作)
  10. azure云数据库_Azure SQL数据库中的地理复制