获取指定包下所有接口实现类
- 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 private static 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