类操作工具类
工具 操作
2023-09-27 14:20:23 时间
package hjp.smart4j.framework.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileFilter; import java.net.JarURLConnection; import java.net.URL; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; /** * 类操作工具类 */ public final class ClassUtil { private static final Logger LOGGER = LoggerFactory.getLogger(ClassUtil.class); /** * 获取类加载器 */ public static ClassLoader getClassLoader() { return Thread.currentThread().getContextClassLoader(); } /** * 加载类 * className为类的全包名 */ public static Class<?> loadClass(String className, boolean isInitialized) { Class<?> cls; try { cls = Class.forName(className, isInitialized, getClassLoader()); } catch (ClassNotFoundException e) { LOGGER.error("load class failure", e); throw new RuntimeException(); } return cls; } /** * 获取指定包名下的所有类 */ public static Set<Class<?>> getClassSet(String packageName) { Set<Class<?>> classSet = new HashSet<Class<?>>(); try { Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".", "/")); while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (url != null) { String protocol = url.getProtocol();//url协议 if (protocol.equals("file")) { String packagePath = url.getPath().replaceAll("%20", " "); addClass(classSet, packagePath, packageName); } else if (protocol.equals("jar")) { JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); if (jarURLConnection != null) { JarFile jarFile = jarURLConnection.getJarFile(); if (jarFile != null) { Enumeration<JarEntry> jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith(".class")) { String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", "."); doAddClass(classSet, className); } } } } } } } } catch (Exception e) { LOGGER.error("get class set failure", e); throw new RuntimeException(e); } return classSet; } private static void addClass(Set<Class<?>> classSet, String packagePath, String packageName) { final File[] files = new File(packagePath).listFiles(new FileFilter() { public boolean accept(File file) { //过滤出Class文件或文件夹 return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory(); } }); for (File file : files) { String fileName = file.getName(); if (file.isFile()) { //如果是类文件构造类文件全包名 String className = fileName.substring(0, fileName.lastIndexOf(".")); if (StringUtil.isNotEmpty(packageName)) { className = packageName + "." + className; } doAddClass(classSet, className);//这个方法就是用Class.forName方法得到类,加到classSet集合中 } else { //如果是文件夹 //构造此文件夹相对路径 String subPacakgePath = fileName; if (StringUtil.isNotEmpty(subPacakgePath)) { subPacakgePath = packagePath + "/" + subPacakgePath; } //构造此文件夹包名路径 String subPacakgeName = fileName; if (StringUtil.isNotEmpty(subPacakgeName)) { subPacakgeName = packageName + "." + subPacakgeName; } //递归加载类 addClass(classSet, subPacakgePath, subPacakgeName); } } } private static void doAddClass(Set<Class<?>> classSet, String className) { Class<?> cls = loadClass(className, false); classSet.add(cls); } }
1、通过类加载器,得到指定路径下所有资源,返回Enumeration<URL>集合
2、类文件要么是以.class结尾的文件,要么是在jar包中以.class结尾的文件
3、URL 统一资源定位器,遍历Enumeration<URL>集合,分别处理url协议为file或jar的文件
4、如果是file协议,分两种,一种是文件,另一种是文件夹;得到file协议的每一个class格式文件,分析出该class文件全包名,Class.forName方法得到该类
5、如果是jar协议,得到jar包内文件,遍历得到class格式文件,分析出该class文件全包名,Class.forName方法得到该类
相关文章
- pandarallel 是一个简单而有效的工具,可以在所有可用的 CPUs 上并行执行 pandas 操作
- JDBC概述,主要API,CRUD操作,封装jdbcutil工具类,注入攻击问题, Statement与PreparedStatement的区别,数据库连接池,事物操作,批处理
- 字符串工具类、数组工具类、集合工具类、转型操作工具类、编码与解码操作工具类
- 使用ThreadLocal、Apache的dbutils的QueryRunner和dbcp2数据库连接池的BasicDataSource封装操作数据库工具
- 【转载】[C#]枚举操作(从枚举中获取Description,根据Description获取枚举,将枚举转换为ArrayList)工具类
- SharePoint 2019 离线安装准备工具
- [Shell] Windows上支持Linux Shell的工具/方法
- [软件过程/软件生命周期模型]软件过程的工具链&技术链【待续】
- SQL优化工具SQLAdvisor使用(转)
- ubuntu安装mysql可视化工具MySQL-workbench及简单操作
- Flyway-数据库迁移工具
- WebRTC系列-工具系列之RTC_DCHECK、RTC_CHECK,字符串操作
- 一款超强的手机屏幕投影工具
- .NET Core(C#) 反射类的属性(PropertyInfo)、字段(FieldInfo)和方法(MethodInfo)相关操作扩展方法工具类
- 简单的多线程同步的小工具类
- 大数据ClickHouse(二十):ClickHouse 可视化工具操作
- Fail2ban用来作DDOS防守工具,不知够不够份量
- 图片压缩操作工具类
- 7个杀手级的开源监测工具
- 四十三、python学习之Django框架(三):数据库,数据库配置,定义模型,shell工具,数据库操作,查询集