Java扫描指定包中所有类

1. 扫描类

Java代码  收藏代码
  1. import java.io.File;  
  2. import java.io.FilenameFilter;  
  3. import java.io.IOException;  
  4. import java.net.JarURLConnection;  
  5. import java.net.URL;  
  6. import java.util.Enumeration;  
  7. import java.util.HashMap;  
  8. import java.util.Map;  
  9. import java.util.jar.JarEntry;  
  10. import java.util.jar.JarFile;  
  11.   
  12. import com.cnp.andromeda.common.util.StringUtil;  
  13.   
  14. /** 
  15.  * @Author 
  16.  * @Description 包扫描器 
  17.  * @CopyRight  
  18.  */  
  19. public class ClassScanner{  
  20.     private Map<String, Class<?>> classes           = new HashMap<String, Class<?>>();  
  21.     private FilenameFilter        javaClassFilter;                                    // 类文件过滤器,只扫描一级类  
  22.     private final String          CLASS_FILE_SUFFIX = ".class";                       // Java字节码文件后缀  
  23.     private String                packPrefix;                                         // 包路径根路劲  
  24.   
  25.     public ClassScanner(){  
  26.         javaClassFilter = new FilenameFilter(){  
  27.             @Override  
  28.             public boolean accept(File dir, String name){  
  29.                 // 排除内部内  
  30.                 return !name.contains("$");  
  31.             }  
  32.         };  
  33.     }  
  34.   
  35.     /** 
  36.      * @Title: scanning 
  37.      * @Description 扫描指定包(本地) 
  38.      * @param basePath 包所在的根路径 
  39.      * @param packagePath 目标包路径 
  40.      * @return Integer 被扫描到的类的数量 
  41.      * @throws ClassNotFoundException 
  42.      */  
  43.     public Integer scanning(String basePath, String packagePath) throws ClassNotFoundException{  
  44.         packPrefix = basePath;  
  45.   
  46.         String packTmp = packagePath.replace('.', '/');  
  47.         File dir = new File(basePath, packTmp);  
  48.   
  49.         // 不是文件夹  
  50.         if(dir.isDirectory()){  
  51.             scan0(dir);  
  52.         }  
  53.   
  54.         return classes.size();  
  55.     }  
  56.   
  57.     /** 
  58.      * @Title: scanning 
  59.      * @Description 扫描指定包, Jar或本地 
  60.      * @param packagePath 包路径 
  61.      * @param recursive 是否扫描子包 
  62.      * @return Integer 类数量 
  63.      */  
  64.     public Integer scanning(String packagePath, boolean recursive){  
  65.         Enumeration<URL> dir;  
  66.         String filePackPath = packagePath.replace('.', '/');  
  67.         try{  
  68.             // 得到指定路径中所有的资源文件  
  69.             dir = Thread.currentThread().getContextClassLoader().getResources(filePackPath);  
  70.             packPrefix = Thread.currentThread().getContextClassLoader().getResource("").getPath();  
  71.             if(System.getProperty("file.separator").equals("\")){  
  72.                 packPrefix = packPrefix.substring(1);  
  73.             }  
  74.   
  75.             // 遍历资源文件  
  76.             while(dir.hasMoreElements()){  
  77.                 URL url = dir.nextElement();  
  78.                 String protocol = url.getProtocol();  
  79.   
  80.                 if("file".equals(protocol)){  
  81.                     File file = new File(url.getPath().substring(1));  
  82.                     scan0(file);  
  83.                 } else if("jar".equals(protocol)){  
  84.                     scanJ(url, recursive);  
  85.                 }  
  86.             }  
  87.         }  
  88.         catch(Exception e){  
  89.             throw new RuntimeException(e);  
  90.         }  
  91.   
  92.         return classes.size();  
  93.     }  
  94.   
  95.     /** 
  96.      * @Title: scanJ 
  97.      * @Description 扫描Jar包下所有class 
  98.      * @param url jar-url路径 
  99.      * @param recursive 是否递归遍历子包 
  100.      * @throws IOException 
  101.      * @throws ClassNotFoundException 
  102.      */  
  103.     private void scanJ(URL url, boolean recursive) throws IOException, ClassNotFoundException{  
  104.         JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection();  
  105.         JarFile jarFile = jarURLConnection.getJarFile();  
  106.   
  107.         // 遍历Jar包  
  108.         Enumeration<JarEntry> entries = jarFile.entries();  
  109.         while(entries.hasMoreElements()){  
  110.             JarEntry jarEntry = (JarEntry)entries.nextElement();  
  111.             String fileName = jarEntry.getName();  
  112.   
  113.             if (jarEntry.isDirectory()) {  
  114.                 if (recursive) {  
  115.                 }  
  116.                 continue;  
  117.             }  
  118.               
  119.             // .class  
  120.             if(fileName.endsWith(CLASS_FILE_SUFFIX)){  
  121.                 String className = fileName.substring(0, fileName.indexOf('.')).replace('/', '.');  
  122.                 classes.put(className, Class.forName(className));  
  123.             }  
  124.   
  125.         }  
  126.     }  
  127.   
  128.     /** 
  129.      * @Title: scan0 
  130.      * @Description 执行扫描 
  131.      * @param dir Java包文件夹 
  132.      * @throws ClassNotFoundException 
  133.      */  
  134.     private void scan0(File dir) throws ClassNotFoundException{  
  135.         File[] fs = dir.listFiles(javaClassFilter);  
  136.         for(int i = 0; fs != null && i < fs.length; i++){  
  137.             File f = fs[i];  
  138.             String path = f.getAbsolutePath();  
  139.               
  140.             // 跳过其他文件  
  141.             if(path.endsWith(CLASS_FILE_SUFFIX)){  
  142.                 String className = StringUtil.getPackageByPath(f, packPrefix); // 获取包名  
  143.                 classes.put(className, Class.forName(className));  
  144.             }  
  145.         }  
  146.     }  
  147.   
  148.     /** 
  149.      * @Title: getClasses 
  150.      * @Description 获取包中所有类 
  151.      * @return Map&lt;String,Class&lt;?&gt;&gt; K:类全名, V:Class字节码 
  152.      */  
  153.     public Map<String, Class<?>> getClasses(){  
  154.         return classes;  
  155.     }  
  156.   
  157.     public static void main(String[] args) throws ClassNotFoundException{  
  158.         ClassScanner cs = new ClassScanner();  
  159.         int c = cs.scanning("W:/IWiFI/Code/trunk/operation/target/classes/", "com/cnp/andromeda/common/util/");  
  160.         System.out.println(c);  
  161.         System.out.println(cs.getClasses().keySet());  
  162.   
  163.         ClassScanner cs2 = new ClassScanner();  
  164.         int c2 = cs2.scanning("com.cnp.swarm", false);  
  165.         System.out.println(c2);  
  166.         System.out.println(cs2.getClasses().keySet());  
  167.     }  
  168. }  

2. 依赖工具类

Java代码  收藏代码
  1. import java.io.File;  
  2.   
  3. /** 
  4.  * @FileName: StringUtil.java 
  5.  * @Author  
  6.  * @Description: 
  7.  * @Date 2014年11月16日 上午10:04:03 
  8.  * @CopyRight  
  9.  */  
  10.   
  11. /** 
  12.  * 字符串工具类 
  13.  */  
  14. public final class StringUtil {  
  15.   
  16.     /** 
  17.      * @Title: getMethodName 
  18.      * @Description: 获取对象类型属性的get方法名 
  19.      * @param propertyName 
  20.      *            属性名 
  21.      * @return String "get"开头且参数(propertyName)值首字母大写的字符串 
  22.      */  
  23.     public static String convertToReflectGetMethod(String propertyName) {  
  24.         return "get" + toFirstUpChar(propertyName);  
  25.     }  
  26.   
  27.     /** 
  28.      * @Title: convertToReflectSetMethod 
  29.      * @Description: 获取对象类型属性的set方法名 
  30.      * @param propertyName 
  31.      *            属性名 
  32.      * @return String "set"开头且参数(propertyName)值首字母大写的字符串 
  33.      */  
  34.     public static String convertToReflectSetMethod(String propertyName) {  
  35.         return "set" + toFirstUpChar(propertyName);  
  36.     }  
  37.   
  38.     /** 
  39.      * @Title: toFirstUpChar 
  40.      * @Description: 将字符串的首字母大写 
  41.      * @param target 
  42.      *            目标字符串 
  43.      * @return String 首字母大写的字符串 
  44.      */  
  45.     public static String toFirstUpChar(String target) {  
  46.         StringBuilder sb = new StringBuilder(target);  
  47.         sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));  
  48.         return sb.toString();  
  49.     }  
  50.   
  51.     /** 
  52.      * @Title: getFileSuffixName 
  53.      * @Description: 获取文件名后缀 
  54.      * @param fileName 
  55.      *            文件名 
  56.      * @return String 文件名后缀。如:jpg 
  57.      */  
  58.     public static String getFileSuffixName(String fileName) {  
  59.         return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();  
  60.     }  
  61.   
  62.     /** 
  63.      *  
  64.      * @Title: checkStringIsNotEmpty 
  65.      * @Description:验证字符串是否不为空 
  66.      * @param stringValue 
  67.      *            传入要验证的字符串 
  68.      * @return boolean true:不为 空 或 不为null; false:值为 空 或 为null 
  69.      */  
  70.     public static boolean isNotEmpty(String stringValue) {  
  71.         if (null == stringValue || "".equals(stringValue.trim())) {  
  72.             return false;  
  73.         }  
  74.         return true;  
  75.     }  
  76.   
  77.     /**    
  78.      * @Title: getPackageByPath    
  79.      * @Description 通过指定文件获取类全名   
  80.      * @param classFile 类文件 
  81.      * @return String 类全名 
  82.      */  
  83.     public static String getPackageByPath(File classFile, String exclude){  
  84.         if(classFile == null || classFile.isDirectory()){  
  85.             return null;  
  86.         }  
  87.           
  88.         String path = classFile.getAbsolutePath().replace('\', '/');  
  89.   
  90.         path = path.substring(path.indexOf(exclude) + exclude.length()).replace('/', '.');  
  91.         if(path.startsWith(".")){  
  92.             path = path.substring(1);  
  93.         }  
  94.         if(path.endsWith(".")){  
  95.             path = path.substring(0, path.length() - 1);  
  96.         }  
  97.   
  98.         return path.substring(0, path.lastIndexOf('.'));  
  99.     }  
  100. }  

 

原文地址:https://www.cnblogs.com/xm1-ybtk/p/5112015.html