我的编程空间,编程开发者的网络收藏夹
学习永远不晚

java如何实现一个扫描包的工具类

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

java如何实现一个扫描包的工具类

小编给大家分享一下java如何实现一个扫描包的工具类,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

前言

在很多的实际场景中,我们需要得到某个包名下面所有的类,比如我们在使用SpringMVC的时候,知道SpringMVC可以扫描指定包下的所有类,

代码如下:

package com.gujin.utils;import java.io.File;import java.io.FileFilter;import java.io.IOException;import java.net.JarURLConnection;import java.net.URL;import java.net.URLDecoder;import java.util.ArrayList;import java.util.Enumeration;import java.util.List;import java.util.jar.JarEntry;import java.util.jar.JarFile;public class HQScanPackage{  boolean recursive = true;  private List<String> packageNames = new ArrayList<String>();  private HQScanPackageFilter filter = null;  private HQScanPackageListener listener = null;  public boolean isRecursive() {  return recursive; }  public void setRecursive(boolean recursive) {  this.recursive = recursive; }  public HQScanPackageFilter getFilter() {  return filter; }  public void setFilter(HQScanPackageFilter filter) {  this.filter = filter; }  public HQScanPackageListener getListener() {  return listener; }  public void setListener(HQScanPackageListener listener) {  this.listener = listener; }  public void addPackage(String packageName) {  if (packageName == null || !packageName.matches("[\\w]+(\\.[\\w]+)*"))  {   throw new IllegalArgumentException("非法包名.");  }  this.packageNames.add(packageName); }  public void clearPackage() {  this.packageNames.clear(); }  public void scan() {  for (String packageName : packageNames)  {   scan(packageName);  } }  private boolean accept(Class<?> clazz) {  if (this.filter != null)  {   return this.filter.accept(clazz);  }  return true; }  private void trrigerOnScanClass(Class<?> clazz) {  if (this.listener != null)  {   this.listener.onScanClass(clazz);  } }  private void onScanClass(Class<?> clazz) {  if (accept(clazz))  {   trrigerOnScanClass(clazz);  } }  private void scan(String packageName) {  // 获取包的名字 并进行替换  String packageDirName = packageName.replace('.', '/');  // 定义一个枚举的集合 并进行循环来处理这个目录下的things  Enumeration<URL> dirs = null;  try  {   dirs = Thread.currentThread().getContextClassLoader()    .getResources(packageDirName);   // 循环迭代下去   while (dirs.hasMoreElements())   {   // 获取下一个元素   URL url = dirs.nextElement();   // 得到协议的名称   String protocol = url.getProtocol();   // 如果是以文件的形式保存在服务器上   if ("file".equals(protocol))   {    // 获取包的物理路径    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");    // 以文件的方式扫描整个包下的文件 并添加到集合中    findAndAddClassesInPackageByFile(packageName, filePath);   }   else if ("jar".equals(protocol))   {    // 如果是jar包文件    // 定义一个JarFile    JarFile jar = null;    try    {     // 获取jar     jar = ((JarURLConnection) url.openConnection()).getJarFile();     // 从此jar包 得到一个枚举类     Enumeration<JarEntry> entries = jar.entries();     // 同样的进行循环迭代     while (entries.hasMoreElements())     {      // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件      JarEntry entry = entries.nextElement();      String name = entry.getName();      // 如果是以/开头的      if (name.charAt(0) == '/')      {      // 获取后面的字符串      name = name.substring(1);      }      // 如果前半部分和定义的包名相同      if (name.startsWith(packageDirName))      {      int idx = name.lastIndexOf('/');      // 如果以"/"结尾 是一个包      if (idx != -1)      {       // 获取包名 把"/"替换成"."       packageName = name.substring(0, idx).replace('/',         '.');      }      // 如果可以迭代下去 并且是一个包      if ((idx != -1) || recursive)      {       // 如果是一个.class文件 而且不是目录       if (name.endsWith(".class") && !entry.isDirectory())       {        // 去掉后面的".class" 获取真正的类名        String className = name.substring(         packageName.length() + 1,         name.length() - 6);        try        {         // 添加到classes         // 使用Class.forName会触发类静态方法         Class<?> clazz = Thread.currentThread()          .getContextClassLoader().loadClass(            packageName + '.' + className);         onScanClass(clazz);        }        catch (ClassNotFoundException e)        {         System.err.println("加载类出错");        }       }      }      }     }    }    catch (IOException e)    {     System.err.println("在扫描用户定义视图时从jar包获取文件出错");     e.printStackTrace();    }   }   }  }  catch (IOException e)  {   System.err.println("扫描出错");   e.printStackTrace();  } }  private void findAndAddClassesInPackageByFile(String packageName,   String packagePath) {  // 获取此包的目录 建立一个File  File dir = new File(packagePath);  // 如果不存在或者 也不是目录就直接返回  if (!dir.exists() || !dir.isDirectory())  {   System.err.println("用户定义包名 " + packageName + " 下没有任何文件");   return;  }  // 如果存在 就获取包下的所有文件 包括目录  File[] dirfiles = dir.listFiles(new FileFilter()  {   // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)   public boolean accept(File file)   {   return (recursive && file.isDirectory())     || (file.getName().endsWith(".class"));   }  });  // 循环所有文件  for (File file : dirfiles)  {   // 如果是目录 则继续扫描   if (file.isDirectory())   {   findAndAddClassesInPackageByFile(packageName + "." + file.getName(),     file.getAbsolutePath());   }   else   {   // 如果是java类文件 去掉后面的.class 只留下类名   String className = file.getName().substring(0,     file.getName().length() - 6);   try   {    Class<?> clazz = Thread.currentThread().getContextClassLoader()      .loadClass(packageName + '.' + className);    onScanClass(clazz);   }   catch (ClassNotFoundException e)   {    System.err.println("添加用户自定义视图类错误 找不到此类的.class文件");    e.printStackTrace();   }   }  } }  public static interface HQScanPackageFilter {    public boolean accept(Class<?> clazz); }  public static interface HQScanPackageListener {    public void onScanClass(Class<?> clazz); } public static void main(String[] args) {  HQScanPackage scanPackage = new HQScanPackage();  scanPackage.addPackage(HQScanPackage.class.getPackage().getName());  scanPackage.setFilter(new HQScanPackageFilter()  {   @Override   public boolean accept(Class<?> clazz)   {   return true;   }  });  scanPackage.setListener(new HQScanPackageListener()  {   @Override   public void onScanClass(Class<?> clazz)   {   System.out.println(clazz);   }  });  scanPackage.scan(); }}

运行可以得到如下结果:

class com.gujin.utils.HQScanPackage$1 class com.gujin.utils.HQScanPackage$2 class com.gujin.utils.HQScanPackage$3 interface com.gujin.utils.HQScanPackage$HQScanPackageFilter interface com.gujin.utils.HQScanPackage$HQScanPackageListener class com.gujin.utils.HQScanPackage

以上是“java如何实现一个扫描包的工具类”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

java如何实现一个扫描包的工具类

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java如何实现一个扫描包的工具类

小编给大家分享一下java如何实现一个扫描包的工具类,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言在很多的实际场景中,我们需要得到某个包名下面所有的类,比如我
2023-05-31

利用Java怎么实现一个超时工具类

本文章向大家介绍利用Java怎么实现一个超时工具类的基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程
2023-06-06

如何在java中封装一个JDBC工具类

如何在java中封装一个JDBC工具类?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布
2023-06-14

java中DateUtils时间工具类如何实现

这篇文章将为大家详细讲解有关java中DateUtils时间工具类如何实现,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体内容如下package com.example.administrator.my
2023-05-30

Java如何实现操作JSON的便捷工具类

这篇文章将为大家详细讲解有关Java如何实现操作JSON的便捷工具类,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:对于JSON数据格式的处理,自开发Java以来,已用过多种JSON的开源工具,用
2023-05-30

Java如何实现日期处理工具类DateUtils

小编给大家分享一下Java如何实现日期处理工具类DateUtils,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体内容如下import java.sql.Tim
2023-05-30

java如何调用另一个包里的类

要调用另一个包里的类,需要按照以下步骤进行操作:1. 导入需要调用的类所在的包。使用`import`关键字来导入需要的包,例如:```javaimport com.example.packageName.ClassName;```这里的`c
2023-08-18

使用Java怎么实现一个3des加密解密工具类

这期内容当中小编将会给大家带来有关使用Java怎么实现一个3des加密解密工具类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。具体如下:package com.gcloud.common;import o
2023-05-30

如何在Java中自定义封装一个JDBC工具类

如何在Java中自定义封装一个JDBC工具类?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。步骤① 创建配置文件(config.properties),用于存放注册驱动和连接
2023-06-06

如何在JAVA项目中利用FTPClient工具类实现一个上传下载功能

如何在JAVA项目中利用FTPClient工具类实现一个上传下载功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1、写一个javabean文件,描述ftp上传
2023-05-31

Java工具类如何实现音频音量提升

这篇文章给大家分享的是有关Java工具类如何实现音频音量提升的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Maven依赖 cn.hutool
2023-06-21

基于Java如何实现进制转换工具类

这篇文章主要介绍了基于Java如何实现进制转换工具类的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于Java如何实现进制转换工具类文章都会有所收获,下面我们一起来看看吧。背景最近有个发送短信的功能,需要在短信
2023-07-05

Java类如何实现一个类的障眼法(JadClipse的bug)

这篇文章主要介绍了Java类实现一个类的障眼法(JadClipse的bug),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-12-29

如何在Java中实现一个大数类

如何在Java中实现一个大数类?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java中的大数类简单实现Java中的大数还是挺好用,而且很方便,所以将其罗列如下,
2023-05-31

Java 中如何实现一个像 String 一样不可变的类?

我们思考一下,上面的代码是否真正的做到了不可变,好,我们思考三秒钟,心里默默的数三下。
StringJava2024-12-01

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录