1 ackage io.renren.common; 2 3 import lombok.extern.slf4j.Slf4j; 4 import org.apache.commons.lang3.StringUtils; 5 6 import java.io.File; 7 import java.io.FileFilter; 8 import java.io.IOException; 9 import java.net.JarURLConnection; 10 import java.net.URL; 11 import java.util.Enumeration; 12 import java.util.HashSet; 13 import java.util.Set; 14 import java.util.jar.JarEntry; 15 import java.util.jar.JarFile; 16 17 @Slf4j 18 public class ClassUtil { 19 20 /** 21 * 获取类加载器 22 * 获取加载器类的实现比较简单,只需获取当前线程的ClassLoader 23 */ 24 public static ClassLoader getClassLoader() { 25 return Thread.currentThread().getContextClassLoader(); 26 } 27 28 /** 29 * ** 30 * 加载类 31 * 加载类需要提供类名与是否初始化的标志,这里提到的初始化指是否执行类的静态代码块; 32 * 为了提高加载类的性能,可以将loadClass方法的isInitialized参数设置false 33 */ 34 public static Class<?> loadClass(String className, boolean isInitialized) { 35 Class<?> cls = null; 36 try { 37 cls= Class.forName(className, isInitialized, getClassLoader()); 38 } catch (ClassNotFoundException e) { 39 log.error("load class failure.", e); 40 throw new RuntimeException(e); 41 } 42 return cls; 43 } 44 45 /** 46 * 获取指定包名下的所有类 47 */ 48 public static Set<Class<?>> getClassSet(String packageName) { 49 Set<Class<?>> classSet = new HashSet<Class<?>>(); 50 try { 51 Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".", "/")); 52 while (urls.hasMoreElements()) { 53 URL url = urls.nextElement(); 54 if (url != null) { 55 String protocol = url.getProtocol(); 56 if ("file".equals(protocol)) { 57 String packagePath = url.getPath().replace("%20", ""); 58 addClass(classSet, packagePath, packageName); 59 } else if ("jar".equals(protocol)) { 60 JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); 61 if (jarURLConnection != null) { 62 JarFile jarFile = jarURLConnection.getJarFile(); 63 if (jarFile != null) { 64 Enumeration<JarEntry> jarEntries = jarFile.entries(); 65 while (jarEntries.hasMoreElements()) { 66 JarEntry jarEntry = jarEntries.nextElement(); 67 String jarEntryName = jarEntry.getName(); 68 if (jarEntryName.endsWith(".class")) { 69 String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")) 70 .replaceAll("/", "."); 71 doAddClass(classSet, className); 72 } 73 } 74 } 75 } 76 } 77 } 78 } 79 } catch (IOException e) { 80 log.error("get class set failure.", e); 81 throw new RuntimeException(e); 82 } 83 return classSet; 84 } 85 86 private static void addClass(Set<Class<?>> classSet, String packagePath, String packageName) { 87 File[] files = new File(packagePath).listFiles(new FileFilter() { 88 public boolean accept(File file) { 89 return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory(); 90 } 91 }); 92 for (File file : files) { 93 String fileName = file.getName(); 94 if (file.isFile()) { 95 String className = fileName.substring(0, fileName.lastIndexOf(".")); 96 if (StringUtils.isNotEmpty(packageName)) { 97 className = packageName + "." + className; 98 } 99 doAddClass(classSet, className); 100 } else { 101 String subPackagePath = fileName; 102 if (StringUtils.isNotEmpty(packageName)) { 103 subPackagePath = packagePath + "/" + subPackagePath; 104 } 105 String subPackageName = fileName; 106 if (StringUtils.isNotEmpty(packageName)) { 107 subPackageName = packageName + "." + subPackageName; 108 } 109 addClass(classSet, subPackagePath, subPackageName); 110 } 111 } 112 } 113 114 private static void doAddClass(Set<Class<?>> classSet, String className) { 115 Class<?> cls = loadClass(className, true); 116 classSet.add(cls); 117 }
实现扫描包路径下类的功能