Java中的包扫描(工具)
在现在好多应用场景中,我们需要得到某个包名下面所有的类, 包括我们自己在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中的包扫描(工具)相关推荐
- java.lang包有哪些类_Java中Lang包的工具类有哪些
Java中Lang包的工具类有哪些 发布时间:2020-12-08 16:15:36 来源:亿速云 阅读:76 作者:Leah 今天就跟大家聊聊有关Java中Lang包的工具类有哪些,可能很多人都不太 ...
- jar包扫描工具: gamma
1. 简介 本项目是一个jar包扫描工具,可以支持插件化订制不同的扫描逻辑 支持以下功能: 插件化订制扫描逻辑,让扩展更加容易 将扫描到的文件加载到jvm中以class的形式返回给处理插件,让扫描逻辑 ...
- golang中的包管理工具——govendor和godep简单学习
为什么用vendor目录 依赖问题 我们知道,一个工程稍大一点,通常会依赖各种各样的包.而Go使用统一的GOPATH管理依赖包,且每个包仅保留一个版本.而不同的依赖包由各自的版本工具独立管理,所以当所 ...
- ssm项目配置文件中的包扫描bean,排除特定bean的扫描
ssm项目配置文件中的包扫描bean springMVC.xml: 自动扫描controller包下的所有类,使其认为spring mvc的控制器 <!-- 自动扫描controller包下的所 ...
- java中常用的加密工具
java中常用的加密工具 1. md5加密工具类 public class MD5Utils {private static final String hexDigIts[] = {"0&q ...
- Java中的包(package)详情解释
一.Java 包(package) 为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间. 包的作用 1.把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2.如同文件夹一 ...
- Java中jar包怎么使用_java中jar包的使用方法
java中jar包的使用方法 发布时间:2020-06-23 11:08:05 来源:亿速云 阅读:162 作者:Leah 这篇文章将为大家详细讲解有关java中jar包的使用方法,小编觉得挺实用的, ...
- java中常用的日期工具类
java中常用的日期工具类 日期相关的类: package net.yto.ofclacct.core.util;import java.text.ParseException; import jav ...
- 【Java学习笔记四】Java中的包
包的声明和引入:在Java语言系统中,Java编译器为每一个类生成一个字节码文件(.class),为了对类文件进行分层和按用途分类管理,同时也为了解决相同类名的文件冲突的问题,Java提供了包机制来管 ...
最新文章
- undistortPoints()函数用法总结
- JS组件系列——BootstrapTable 行内编辑解决方案:x-editable
- 十 ubus安装编译
- JAVA 判断其是否为合法标识符
- 遍历flex和flash对象的属性和方法
- 月薪3K与月薪3万的程序员,距离是怎么拉开的?
- HTML label控件
- 的电路接法_基本震荡电路知多少,汇总几种震荡电路的接法!
- iOS开发之UI控件阴影效果
- [Python] 当猎头遇上 Guido van Rossum
- Node.js:使用blueimp-md5进行MD5加密
- 《ERP原理》期末复习——第一章 初识ERP(企业资源计划)
- ArcGIS Pro脚本工具(10)——从图层生成.stylx样式符号
- cobar mysql_cobar mysql 高可用
- Guava Joiner
- 二十多年了,安全套市场还只有杜蕾斯、冈本、杰士邦
- 阿里云搭建Tomcat+Jdk+Mysql(阿里云系统CentOs)特完整
- 我叫mt4最新服务器,我叫mt4新区开服表 最新新区开服时间汇总分享[多图]
- 帝国CMS(EmpireCMS) v7.5配置文件写入漏洞分析
- R 回归分析 多元线性回归