獲取指定包下所有介面實現類
阿新 • • 發佈:2020-12-17
1 package com.i2stream.util; 2 3 import org.apache.commons.lang3.time.DateParser; 4 import org.apache.logging.log4j.LogManager; 5 import org.apache.logging.log4j.Logger; 6 7 import java.io.File; 8 import java.io.IOException; 9 import java.net.JarURLConnection; 10 import java.net.URI;11 import java.net.URISyntaxException; 12 import java.net.URL; 13 import java.util.ArrayList; 14 import java.util.Arrays; 15 import java.util.Enumeration; 16 import java.util.List; 17 import java.util.jar.JarEntry; 18 import java.util.jar.JarFile; 19 20 public class PackageScanUtil { 21 privatestatic final Logger LOG = LogManager.getLogger(PackageScanUtil.class); 22 private static final ClassLoader classLoader = PackageScanUtil.class.getClassLoader(); 23 24 public static void main(String[] args) { 25 final List<Class<?>> classes = PackageScanUtil.addClass("org.apache.commons.lang3.time", DateParser.class); 26 if (classes != null) { 27 classes.forEach(cl -> System.out.println(cl.getName())); 28 } 29 } 30 31 /** 32 * Get all the classes under the package that implement the superStrategy and add them to the list 33 */ 34 public static List<Class<?>> addClass(String classPath, Class<?> superStrategy) { 35 URL url = classLoader.getResource(classPath.replace(".", "/")); 36 if (url == null) { 37 LOG.error("{} can not be found", classPath); 38 return null; 39 } 40 String protocol = url.getProtocol(); 41 if ("file".equals(protocol)) { 42 return findLocalClass(classPath, superStrategy); 43 } else if ("jar".equals(protocol)) { 44 return findJarClass(classPath, superStrategy); 45 } else { 46 LOG.error("unknown protocol: {}", classPath); 47 return null; 48 } 49 } 50 51 /** 52 * find class at local 53 */ 54 private static List<Class<?>> findLocalClass(final String classPath, Class<?> superStrategy) { 55 List<Class<?>> eleStrategyList = new ArrayList<>(); 56 URI uri; 57 try { 58 URL url = classLoader.getResource(classPath.replace(".", "/")); 59 if (url == null) { 60 LOG.error("{} can not be found", classPath); 61 return null; 62 } else { 63 uri = url.toURI(); 64 } 65 } catch (URISyntaxException e1) { 66 LOG.error("{} can not be found", classPath); 67 return eleStrategyList; 68 } 69 70 File file = new File(uri); 71 final File[] files = file.listFiles(chiFile -> { 72 if (chiFile.isDirectory()) { 73 findLocalClass(classPath + "." + chiFile.getName(), superStrategy); 74 } 75 if (chiFile.getName().endsWith(".class")) { 76 Class<?> clazz; 77 try { 78 clazz = classLoader.loadClass(classPath + "." + chiFile.getName().replace(".class", "")); 79 } catch (ClassNotFoundException e) { 80 return false; 81 } 82 if (clazz != null && superStrategy.isAssignableFrom(clazz) && !superStrategy.getName().equals(clazz.getName())) { 83 eleStrategyList.add(clazz); 84 return true; 85 } 86 } 87 return false; 88 }); 89 if (files != null && LOG.isTraceEnabled()) { 90 LOG.trace("add class:{}", Arrays.toString(files)); 91 } 92 return eleStrategyList; 93 } 94 95 /** 96 * find class tat jar file 97 */ 98 private static List<Class<?>> findJarClass(String classPath, Class<?> superStrategy) { 99 List<Class<?>> eleStrategyList = new ArrayList<>(); 100 String pathName = classPath.replace(".", "/"); 101 JarFile jarFile; 102 URL url = classLoader.getResource(pathName); 103 if (url == null) { 104 LOG.error("{} can not be found", classPath); 105 return null; 106 } 107 try { 108 JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); 109 jarFile = jarURLConnection.getJarFile(); 110 } catch (IOException e) { 111 LOG.error("{} can not be found", classPath); 112 return null; 113 } 114 115 Enumeration<JarEntry> jarEntries = jarFile.entries(); 116 while (jarEntries.hasMoreElements()) { 117 JarEntry jarEntry = jarEntries.nextElement(); 118 String jarEntryName = jarEntry.getName(); 119 120 if (jarEntryName.contains(pathName) && !jarEntryName.equals(pathName + "/")) { 121 // recursive subclass 122 if (jarEntry.isDirectory()) { 123 String clazzName = jarEntry.getName().replace("/", "."); 124 int endIndex = clazzName.lastIndexOf("."); 125 String prefix = null; 126 if (endIndex > 0) { 127 prefix = clazzName.substring(0, endIndex); 128 } 129 if (prefix == null) { 130 continue; 131 } 132 findJarClass(prefix, superStrategy); 133 } 134 if (jarEntry.getName().endsWith(".class")) { 135 Class<?> clazz; 136 try { 137 clazz = classLoader.loadClass(jarEntry.getName().replace("/", ".").replace(".class", "")); 138 } catch (ClassNotFoundException e) { 139 continue; 140 } 141 if (clazz != null && superStrategy.isAssignableFrom(clazz) && !superStrategy.getName().equals(clazz.getName())) { 142 eleStrategyList.add(clazz); 143 } 144 } 145 } 146 147 } 148 return eleStrategyList; 149 } 150 }
執行main方法輸出如下:
org.apache.commons.lang3.time.FastDateFormat
org.apache.commons.lang3.time.FastDateParser