JAVA 扫描指定路径下所有的jar包,并保存所有实现固定接口的类型
private static Map<String, Object> loadAllJarFromAbsolute(String directoryPath) throws
NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException { File directory = new File(directoryPath);
// 判断是否为文件夹,如果是文件,直接用单个jar解析的方法去解析
if (!directory.isDirectory()) {
// 添加jar扫描路径
addUrl(directory);
return loadJarFromAbsolute(directoryPath);
}
// 如果是文件夹,则需要循环加载当前文件夹下面的所有jar
Map<String, Object> clazzMap = new HashMap<>(16);
File[] jars = directory.listFiles();
if (jars != null && jars.length > 0) {
List<String> jarPath = new LinkedList<>();
for (File file : jars) {
String fPath = file.getPath();
// 只加载jar
if (fPath.endsWith(".jar")) {
addUrl(file);
jarPath.add(fPath);
}
}
if (jarPath.size() > 0) {
for (String path : jarPath) {
clazzMap.putAll(loadJarFromAbsolute(path));
}
}
}
return clazzMap;
} private static Map<String, Object> loadJarFromAbsolute(String path) throws IOException {
JarFile jar = new JarFile(path);
Enumeration<JarEntry> entryEnumeration = jar.entries();
Map<String, Object> clazzMap = new HashMap<>(32);
while (entryEnumeration.hasMoreElements()) {
JarEntry entry = entryEnumeration.nextElement();
// 先获取类的名称,符合条件之后再做处理,避免处理不符合条件的类
String clazzName = entry.getName();
if (clazzName.endsWith(".class")) {
// 去掉文件名的后缀
clazzName = clazzName.substring(0, clazzName.length() - 6);
// 替换分隔符
clazzName = clazzName.replace("/", ".");
// 加载类,如果失败直接跳过
try {
Class<?> clazz = Class.forName(clazzName);
Class superClass = clazz.getSuperclass();
if (superClass.equals(ComponentExtend.class)) {
Object o = clazz.newInstance();
Method fieldExtendComponentId = clazz.getMethod("extendComponentId");
String id = (String) fieldExtendComponentId.invoke(o);
clazzMap.put(id, o);
}
} catch (Throwable e) {
// 这里可能出现有些类是依赖不全的,直接跳过,不做处理,也没法做处理
}
}
}
return clazzMap;
} private static void addUrl(File jarPath) throws NoSuchMethodException, InvocationTargetException,
IllegalAccessException, MalformedURLException { URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
if (!method.isAccessible()) {
method.setAccessible(true);
}
URL url = jarPath.toURI().toURL();
// 把当前jar的路径加入到类加载器需要扫描的路径
method.invoke(classLoader, url);
}
JAVA 扫描指定路径下所有的jar包,并保存所有实现固定接口的类型的更多相关文章
- java监控指定路径下文件及文件夹变化
之前用jdk7的WatchService API(java.nio.file包)来做目录下的子文件监控,后改为使用commons-io包.主要有下面几点不同:1. WatchService是采用扫描式 ...
- java获取指定路径下的指定文件/java.io.File.listFiles(FilenameFilter filter)
java.io.File.listFiles(FilenameFilter filter) 返回抽象路径名数组,表示在目录中此抽象路径名表示,满足指定过滤器的文件和目录. 声明 以下是java.io. ...
- Python—导入自定义的模块和包(指定路径下的模块和包)
模块路径如下图: import sys sys.path.append(r"E:\project\path") print "===>", sys.arg ...
- java 压缩文件 传入文件数组,压缩文件,在指定路径下生成指定文件名的压缩文件
/** * 传入文件数组,压缩文件,在指定路径下生成指定文件名的压缩文件 * * @param files * 文件数组 * @param strZipName * 压缩文件路径及文件名 * @thr ...
- java读取指定package下的所有class
JAVA如何扫描一个包下面的所有类,并加载到内存中去? spring中有一个<context:component-scan base-package="com.controller& ...
- Java 读取指定目录下的文件名和目录名
需求:读取指定目录下的文件名和目录名 实现如下: package com.test.common.util; import java.io.File; public class ReadFile { ...
- C#实现把指定文件夹下的所有文件复制到指定路径下以及修改指定文件的后缀名
1.实现把指定文件夹下的所有文件复制到指定路径下 public static void copyFiles(string path) { DirectoryInfo dir = new Directo ...
- matlab读取指定路径下的图像
利用matlab读取指定路径下的图像 %% 读入指定路径imgFolder下的图像imgName imgFolder = 'F:\博\快盘\图像+数据\images\文章实验图'; %指定路径 img ...
- 指定路径下建立Access数据库并插入数据
今天刚刚开通博客,想要把我这几天完成小任务的过程,记录下来.我从事软件开发的时间不到1年,写的不足之处,还请前辈们多多指教. 上周四也就是2016-04-14号上午,部门领导交给我一个小任务,概括来讲 ...
随机推荐
- 如何保证javascript算数计算结果的精度
前言: 我们先看如下这个js的代数计算结果,什么? 明显不是我们想要的结果3.52!! 备注:其实这个小数计算精度问题,在弱类型语言python等语言中同样存在. 问题原因之所在: JavaScrip ...
- apache-maven安装
1.下载maven 网址:http://maven.apache.org 2.下载maven和安装 由于最新版的可能会有问题,我选择下载旧版本 一般都下载二进制的zip文件 解压后文件夹apache- ...
- CSP-2019酱油记
炸了 Day0 上午机房弥漫着颓废的气息... nc哥在疯狂打板子,我疯狂找水题找信心(然而被历次联赛T1爆切 退役气息稍重,好多人刷屏cnblogs.. 然后年级扛把子们来做指♂导啦- 准备了火龙果 ...
- LINUX下的gdb调试方法
首先对目标文件进行编译 例如: gcc test.c -o test 这时会生成一个文件test,然后我们就可以对test进行调试了 示例: gdb test 好了以后是设定断点 示例: break ...
- TCP/IP协议族基本知识
常见的网络拓扑 两台主机通信的过程:应用进程产生消息,经由主机的 TCP/IP 协议栈发送到局域网(LAN),最后经过广域网(目前最大的广域网的因特网)中的网络设备(路由器)传给目的主机所在的局域网( ...
- mybatis 根据多个id查询数据 foreach标签
//根据设备多个id获取设备信息 public List<Devices> getDevicesAll(@Param("devicesIds") String[] de ...
- 使用grpc C++功能
grpc c++开发需要安装相关工具以及框架才能进行开发. rz 远程上传文件 本地开发环境搭建: 1.编译相关工具 pkg-config autoconf automake Libtool shto ...
- 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)
redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...
- 【Beta】Scrum meeting 6
目录 写在前面 进度情况 任务进度表 Beta-1阶段燃尽图 遇到的困难 照片 commit记录截图 小程序前端仓库 后端代码仓库 技术博客 写在前面 例会时间:5.10 22:30-22:50 例会 ...
- MLflow系列4:MLflow模型
英文链接:https://mlflow.org/docs/latest/models.html 本文链接:https://www.cnblogs.com/CheeseZH/p/11946260.htm ...