ClassUtil.java 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package org.shoulder.maven.plugins.mojo;
  2. import java.io.File;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.LinkedList;
  6. import java.util.List;
  7. /**
  8. * @author lym
  9. */
  10. public class ClassUtil {
  11. public static void main(String[] args) {
  12. getAllSonOfClass(ClassUtil.class.getPackage().getName(), ErrorCode.class);
  13. System.out.println();
  14. }
  15. public static <T> List<Class<? extends T>> getAllSonOfClass(String packageName, Class<T> clazz) {
  16. return filterSonOfClass(getAllClass(packageName), clazz);
  17. }
  18. @SuppressWarnings({"unchecked"})
  19. private static <T> List<Class<? extends T>> filterSonOfClass(Collection<Class<?>> allClass, Class<T> clazz) {
  20. List<Class<? extends T>> list = new LinkedList<>();
  21. try {
  22. for (Class aClass : allClass) {
  23. if (clazz.isAssignableFrom(aClass)) {
  24. // 自身并不加进去
  25. if (!clazz.equals(aClass)) {
  26. list.add(aClass);
  27. }
  28. }
  29. }
  30. } catch (Exception e) {
  31. throw new RuntimeException("error when scan package");
  32. }
  33. return list;
  34. }
  35. /**
  36. * 从一个指定路径下查找所有的类
  37. */
  38. @SuppressWarnings("rawtypes")
  39. private static List<Class<?>> getAllClass(String packageName) {
  40. ArrayList<Class<?>> classes = new ArrayList<>();
  41. //先把包名转换为路径,首先得到项目的classpath
  42. String classpath = ClassUtil.class.getResource("/").getPath();
  43. //然后把我们的包名basPach转换为路径名
  44. packageName = packageName.replace(".", File.separator);
  45. //然后把classpath和basePack合并
  46. String searchPath = classpath + packageName;
  47. List<String> classPaths = new LinkedList<>();
  48. doPath(new File(searchPath), classPaths);
  49. //这个时候我们已经得到了指定包下所有的类的绝对路径了。我们现在利用这些绝对路径和java的反射机制得到他们的类对象
  50. for (String s : classPaths) {
  51. //把 D:\work\code\20170401\search-class\target\classes\com\baibin\search\a\A.class 这样的绝对路径转换为全类名com.baibin.search.a.A
  52. s = s.replace(classpath.replace("/","\\").replaceFirst("\\\\",""),"").replace("\\",".").replace(".class","");
  53. Class cls = null;
  54. try {
  55. cls = Class.forName(s);
  56. } catch (ClassNotFoundException e) {
  57. //log.error("class not found " + s, e);
  58. }
  59. classes.add(cls);
  60. }
  61. return classes;
  62. }
  63. private static void doPath(File file, List<String> allFile) {
  64. if (file.isDirectory()) {
  65. File[] files = file.listFiles();
  66. if (files != null) {
  67. for (File f : files) {
  68. doPath(f, allFile);
  69. }
  70. }
  71. } else {
  72. if (file.getName().endsWith(".class")) {
  73. //如果是class文件我们就放入我们的集合中。
  74. allFile.add(file.getPath());
  75. }
  76. }
  77. }
  78. @FunctionalInterface
  79. interface FileScanFilter {
  80. boolean include(File file);
  81. }
  82. abstract class AbstractFileScanFilter implements FileScanFilter {
  83. protected FileScanFilter delegate;
  84. AbstractFileScanFilter(FileScanFilter delegate) {
  85. this.delegate = delegate;
  86. }
  87. @Override
  88. public boolean include(File file) {
  89. return delegate == null ? isWanted(file) :
  90. delegate.include(file) && isWanted(file);
  91. }
  92. protected abstract boolean isWanted(File file);
  93. }
  94. class ClassFileFilter extends AbstractFileScanFilter {
  95. public ClassFileFilter(FileScanFilter delegate) {
  96. super(delegate);
  97. }
  98. @Override
  99. public boolean isWanted(File file) {
  100. return file.getName().endsWith(".class");
  101. }
  102. }
  103. class SpecialTypeFilter extends ClassFileFilter {
  104. private Class<?> type;
  105. public SpecialTypeFilter(FileScanFilter delegate, Class<?> type) {
  106. super(delegate);
  107. this.type = type;
  108. }
  109. @Override
  110. public boolean isWanted(File file) {
  111. return super.isWanted(file) && type.getTypeName().equals(file.getName().substring(0,
  112. file.getName().length() - ".class".length()));
  113. }
  114. }
  115. }