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

 

运行main方法输出如下:

  1. org.apache.commons.lang3.time.FastDateFormat
  2. org.apache.commons.lang3.time.FastDateParser

 

版权声明:本文为kwing0117原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/kwing0117/p/14151583.html