kwing

获取指定包下所有接口实现类

  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

 

posted on 2020-12-17 19:52  kwing  阅读(351)  评论(1编辑  收藏  举报

导航

返回顶部
>>
<<