java扫描包下类_实现获取扫描指定包路径下的jar文件或class文件JarPojoHandler类示例代码...

该代码实现了一个名为`JarPojoHandler`的类,用于扫描指定路径下的JAR包和class文件。它能够过滤并加载特定的class对象,支持从JAR文件和文件系统目录中获取类。主要方法包括获取指定路径下的JAR文件、从文件加载类、以及获取包下的所有类。此外,还提供了缓存已加载的类和释放资源的功能。
摘要由CSDN通过智能技术生成

通过JarPojoHandler类实现了扫描指定路径下如何获取所有的JAR包或class文件,可以对特定class对象文件筛选过滤等,具体代码如下所示import java.io.File;@b@import java.io.FileFilter;@b@import java.io.IOException;@b@import java.net.JarURLConnection;@b@import java.net.URL;@b@import java.net.URLClassLoader;@b@import java.net.URLDecoder;@b@import java.util.ArrayList;@b@import java.util.Enumeration;@b@import java.util.HashMap;@b@import java.util.LinkedHashSet;@b@import java.util.List;@b@import java.util.Map;@b@import java.util.Set;@b@import java.util.jar.JarEntry;@b@import java.util.jar.JarFile;@b@@b@/**@b@ * 扫描指定包(包括jar)下的class文件 
 @b@ */@b@public class JarPojoHandler {@b@private static Map>> pojoClasses = new HashMap>>();@b@@b@/**@b@ * 获得指定路径下的所有 JAR包@b@ * @param strPath@b@ * @return@b@ */@b@public static List getDirFiles(String strPath) {@b@List list = new ArrayList();@b@File f = new File(strPath);@b@if (f.isDirectory()) {@b@File[] fList = f.listFiles();@b@for (int j = 0; j > getClazzInstances(File file, String packages,@b@String current) {@b@try {@b@if (file == null) return null;@b@URLClassLoader loader = new URLClassLoader(new URL[] { new URL(@b@"file:" + file.getAbsolutePath()) }, Thread.currentThread()@b@.getContextClassLoader());@b@List> classinstances = new ArrayList>();@b@JarFile jarFile = new JarFile(file);@b@Enumeration> enum1 = jarFile.entries();@b@List> clzlist = JarPojoHandler.pojoClasses.get(current);@b@if(clzlist == null ) {@b@clzlist = new ArrayList>();@b@pojoClasses.put(current, clzlist);@b@}@b@while (enum1.hasMoreElements()) {@b@JarEntry entry = (JarEntry) enum1.nextElement();@b@if (entry.isDirectory()) continue;@b@String jar = entry.getName();@b@if (jar.endsWith(".class")) {@b@String clzname = jar.substring(0, jar.lastIndexOf(".class")).replace('/', '.');@b@String clzpackage = clzname.substring(0, clzname.lastIndexOf("."));@b@String currentpackage = packages + "." + current + ".bean";@b@if (clzpackage.equals(currentpackage)) {@b@Class> clz = loader.loadClass(clzname);@b@classinstances.add(clz);@b@}@b@if (clzname.startsWith(packages)) {@b@Class> clz = loader.loadClass(clzname);@b@clzlist.add(clz);@b@}@b@}@b@}@b@if(jarFile != null) jarFile.close();@b@return classinstances;@b@} catch (Exception e) {@b@e.printStackTrace();@b@}@b@return null;@b@}@b@@b@public static Set> getClasses(String pack) {@b@// 第一个class类的集合@b@Set> classes = new LinkedHashSet>();@b@// 是否循环迭代@b@boolean recursive = true;@b@// 获取包的名字 并进行替换@b@String packageName = pack;@b@String packageDirName = packageName.replace('.', '/');@b@// 定义一个枚举的集合 并进行循环来处理这个目录下的things@b@Enumeration dirs;@b@try {@b@dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);@b@// 循环迭代下去@b@while (dirs.hasMoreElements()) {@b@// 获取下一个元素@b@URL url = dirs.nextElement();@b@// 得到协议的名称@b@String protocol = url.getProtocol();@b@// 如果是以文件的形式保存在服务器上@b@if ("file".equals(protocol)) {@b@// file类型的扫描@b@// 获取包的物理路径@b@String filePath = URLDecoder.decode(url.getFile(), "UTF-8");@b@// 以文件的方式扫描整个包下的文件 并添加到集合中@b@findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);@b@} else if ("jar".equals(protocol)) {@b@// 如果是jar包文件@b@// 定义一个JarFile@b@// jar类型的扫描@b@JarFile jar;@b@try {@b@// 获取jar@b@jar = ((JarURLConnection) url.openConnection()).getJarFile();@b@// 从此jar包 得到一个枚举类@b@Enumeration entries = jar.entries();@b@// 同样的进行循环迭代@b@while (entries.hasMoreElements()) {@b@// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件@b@JarEntry entry = entries.nextElement();@b@String name = entry.getName();@b@// 如果是以/开头的@b@if (name.charAt(0) == '/') {@b@// 获取后面的字符串@b@name = name.substring(1);@b@}@b@// 如果前半部分和定义的包名相同@b@if (name.startsWith(packageDirName)) {@b@int idx = name.lastIndexOf('/');@b@// 如果以"/"结尾 是一个包@b@if (idx != -1) {@b@// 获取包名 把"/"替换成"."@b@packageName = name.substring(0, idx).replace('/', '.');@b@}@b@// 如果可以迭代下去 并且是一个包@b@if ((idx != -1) || recursive) {@b@// 如果是一个.class文件 而且不是目录@b@if (name.endsWith(".class") && !entry.isDirectory()) {@b@// 去掉后面的".class" 获取真正的类名@b@String className = name.substring(packageName.length() + 1, name.length() - 6);@b@try {@b@// 添加到classes@b@classes.add(Class.forName(packageName + '.' + className));@b@} catch (ClassNotFoundException e) {@b@// .error("添加用户自定义视图类错误 找不到此类的.class文件");@b@e.printStackTrace();@b@}@b@}@b@}@b@}@b@}@b@} catch (IOException e) {@b@// log.error("在扫描用户定义视图时从jar包获取文件出错");@b@e.printStackTrace();@b@}@b@}@b@}@b@} catch (IOException e) {@b@e.printStackTrace();@b@}@b@return classes;@b@}@b@@b@public static void findAndAddClassesInPackageByFile(String packageName,@b@String packagePath, final boolean recursive, Set> classes) {@b@// 获取此包的目录 建立一个File@b@File dir = new File(packagePath);@b@// 如果不存在或者 也不是目录就直接返回@b@if (!dir.exists() || !dir.isDirectory()) {@b@// log.warn("用户定义包名 " + packageName + " 下没有任何文件");@b@return;@b@}@b@// 如果存在 就获取包下的所有文件 包括目录@b@File[] dirfiles = dir.listFiles(new FileFilter() {@b@// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)@b@public boolean accept(File file) {@b@return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));@b@}@b@});@b@// 循环所有文件@b@for (File file : dirfiles) {@b@// 如果是目录 则继续扫描@b@if (file.isDirectory()) {@b@findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);@b@} else {@b@// 如果是java类文件 去掉后面的.class 只留下类名@b@String className = file.getName().substring(0, file.getName().length() - 6);@b@try {@b@// 添加到集合中去@b@// classes.add(Class.forName(packageName + '.' +  className));@b@// 经过回复同学的提醒,这里用forName有一些不好,会触发static方法,没有使用classLoader的load干净@b@classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));@b@} catch (ClassNotFoundException e) {@b@// log.error("添加用户自定义视图类错误 找不到此类的.class文件");@b@e.printStackTrace();@b@}@b@}@b@}@b@}@b@@b@public static Map>> getPojoClasses() {@b@return pojoClasses;@b@}@b@@b@public static void realese() {@b@pojoClasses.clear();@b@}@b@@b@}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值