del[class]: 删除ClassUtils无用方法

This commit is contained in:
godotg
2022-10-07 12:24:15 +08:00
parent 1434f81621
commit 96768588fc
2 changed files with 1 additions and 196 deletions
@@ -12,21 +12,9 @@
package com.zfoo.protocol.util;
import com.zfoo.protocol.collection.CollectionUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.function.Predicate;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* @author godotg
@@ -34,167 +22,6 @@ import java.util.jar.JarFile;
*/
public abstract class ClassUtils {
public static final String FILE_URL_PROTOCOL = "file";
public static final String JAR_URL_PROTOCOL = "jar";
public static final String CLASS_SUFFIX = ".class";
public static final String JAR_SUFFIX = ".jar";
public static final String ZIP_SUFFIX = ".zip";
public static final char FILE_SEPARATOR = '/';
/*
find the location of the class come from
1.FileTest.class.getResource("")
得到的是当前类FileTest.class文件的URI目录。不包括自己!
如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/
2.FileTest.class.getResource("/")
  得到的是当前的classpath的绝对URI路径。
  如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
3.Thread.currentThread().getContextClassLoader().getResource("")
得到的也是当前ClassPath的绝对URI路径。
   如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
4.FileTest.class.getClassLoader().getResource("")
  得到的也是当前ClassPath的绝对URI路径。
   如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
5.ClassLoader.getSystemResource("")
  得到的也是当前ClassPath的绝对URI路径。
   如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/
 我推荐使用Thread.currentThread().getContextClassLoader().getResource("")来得到当前的classpath的绝对路径的URI表示法。
*/
public static String classLocation(final Class<?> cls) {
AssertionUtils.notNull(cls);
URL result = null;
String clsAsResource = cls.getName().replace(StringUtils.PERIOD, StringUtils.SLASH).concat(CLASS_SUFFIX);
ProtectionDomain pd = cls.getProtectionDomain();
if (pd != null) {
CodeSource cs = pd.getCodeSource();
if (cs != null) {
result = cs.getLocation();
}
if (result != null) {
if (FILE_URL_PROTOCOL.equals(result.getProtocol())) {
try {
// "!/"为分隔符,分割jar包,和jar包里的文件
if (result.toExternalForm().endsWith(JAR_SUFFIX) || result.toExternalForm().endsWith(ZIP_SUFFIX)) {
result = new URL(JAR_URL_PROTOCOL + StringUtils.COLON + result.toExternalForm() + "!/" + clsAsResource);
} else if (new File(result.getFile()).isDirectory()) {
result = new URL(result, clsAsResource);
}
} catch (MalformedURLException ignore) {
}
}
}
}
if (result == null) {
final ClassLoader clsLoader = cls.getClassLoader();
result = clsLoader != null ? clsLoader.getResource(clsAsResource) : ClassLoader.getSystemResource(clsAsResource);
}
return result.toString();
}
/**
* 获取指定包下的所有类,只能搜索当前项目路径和maven项目路径
*
* @param packageName 形如"org.hotswap",不能带有斜线/,以为java格式为主
* @return 当前项目下的所有Java类
* @throws Exception 异常
*/
public static Set<Class<?>> getAllClasses(String packageName) throws Exception {
Set<Class<?>> classSet = new LinkedHashSet<>();
// 定义一个枚举的集合并进行循环来处理这个目录下的things,当前的classpath的绝对路径的URI表示法。
Enumeration<URL> urlEnumeration = Thread.currentThread().getContextClassLoader().getResources(packageName.replace(StringUtils.PERIOD, StringUtils.SLASH));
while (urlEnumeration.hasMoreElements()) {
// 获取下一个元素,如果是jar://得到的结果大概是:jar:file:/C:/Users/ibm/.m2/repository/junit/junit/4.12/junit-4.12.jar!/org/junit
URL url = urlEnumeration.nextElement();
String protocol = url.getProtocol();
if (StringUtils.isBlank(protocol)) {
continue;
}
// file(不打包成jar运行),jar(打包成jar运行)
if (protocol.equals(FILE_URL_PROTOCOL)) {
// 获取包的物理路径
String filePath = URLDecoder.decode(url.getFile(), StringUtils.DEFAULT_CHARSET);
List<File> fileList = FileUtils.getAllReadableFiles(new File(filePath));
for (File file : fileList) {
String fileName = file.getName();
// 不是.class文件和包含美元符号的内部类或者匿名内部类不算
if (!fileName.endsWith(CLASS_SUFFIX) || fileName.contains(StringUtils.DOLLAR)) {
continue;
}
// 如果是java类文件,则去掉后面的.class 只留下类名
String className = StringUtils.substringBeforeLast(fileName, CLASS_SUFFIX);
if (StringUtils.isNotBlank(packageName)) {
String a = StringUtils.substringAfterFirst(file.getAbsolutePath(), FileUtils.getProAbsPath() + File.separator);
a = a.replaceAll(StringUtils.BACK_SLASH + File.separator, StringUtils.PERIOD);
String b = StringUtils.substringBeforeFirst(a, packageName);
String c = StringUtils.substringAfterFirst(a, b);
className = StringUtils.substringBeforeLast(c, CLASS_SUFFIX);
}
classSet.add(Thread.currentThread().getContextClassLoader().loadClass(className));
}
} else if (protocol.equals(JAR_URL_PROTOCOL)) {
JarFile jarFile = ((JarURLConnection) url.openConnection()).getJarFile();
if (jarFile == null) {
continue;
}
//得到该jar文件下面的类实体
Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();
while (jarEntryEnumeration.hasMoreElements()) {
JarEntry entry = jarEntryEnumeration.nextElement();
String jarEntryName = entry.getName();
//这里我们需要过滤不是class文件和不在basePack包名下的类
if (!jarEntryName.contains(CLASS_SUFFIX) || jarEntryName.contains(StringUtils.DOLLAR)) {
continue;
}
String className = StringUtils.substringBeforeLast(jarEntryName, CLASS_SUFFIX).replaceAll(StringUtils.SLASH, StringUtils.PERIOD);
if (!className.startsWith(packageName)) {
continue;
}
classSet.add(Thread.currentThread().getContextClassLoader().loadClass(className));
}
} else {
throw new IllegalStateException(StringUtils.format("不合法的协议文件[protocol:{}]", protocol));
}
}
return classSet;
}
public static List<Class<?>> getClasses(String packageName, Predicate<Class<?>> classFilter) {
Set<Class<?>> allClasses = null;
try {
allClasses = getAllClasses(packageName);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (CollectionUtils.isEmpty(allClasses)) {
return new ArrayList<>();
}
List<Class<?>> list = new ArrayList<>();
if (classFilter == null) {
list.addAll(allClasses);
return list;
}
for (Class<?> clazz : allClasses) {
if (classFilter.test(clazz)) {
list.add(clazz);
}
}
return list;
}
/**
* 获取编译过后的类文件(*.class)的绝对路径
*
@@ -231,8 +58,7 @@ public abstract class ClassUtils {
* @param filePath 一般指resources中的文件,也可以在jar中
*/
public static InputStream getFileFromClassPath(String filePath) throws IOException {
// ClassUtils.getDefaultClassLoader().getResourceAsStream(filePath)
return ClassUtils.getDefaultClassLoader().getResource(filePath).openStream();
return getDefaultClassLoader().getResource(filePath).openStream();
}
}
@@ -13,12 +13,10 @@
package com.zfoo.protocol.util;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.io.IOException;
import java.util.Set;
/**
* @author godotg
@@ -27,30 +25,11 @@ import java.util.Set;
@Ignore
public class ClassUtilsTest {
// ClassUtilTest
@Test
public void classLocation() {
String str = ClassUtils.classLocation(Integer.class);
Assert.assertEquals("jrt:/java.base/java/lang/Integer.class", str);
}
@Test
public void getAllClasses() throws Exception {
System.out.println(StringUtils.MULTIPLE_HYPHENS);
System.out.println("某个包下的所有类查找测试:");
Set<Class<?>> set = ClassUtils.getAllClasses("com.zfoo");
for (Class<?> clazz : set) {
System.out.println(clazz.getName());
}
System.out.println(StringUtils.MULTIPLE_HYPHENS);
}
@Test
public void getClassPath() {
System.out.println(ClassUtils.getClassAbsPath(ClassUtilsTest.class));
}
@Test
public void getClassFromClassPath() throws IOException {
System.out.println(new String(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("csTest/CsProtocolTest.cs"))));