1. Solve the problem: load all classes under the package through the package name in the form of com.xxx.yyy.zzz
2. Code:
package com.chuyutech.rssp.openservice.service.data; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.net.URL; import java.net.URLDecoder; import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.Set; /** * @description: Simple file operation class, including basic operation of some files * * @author cwh * */ public class FileOpreation { /** * Access disk files based on package name * * @param packageName:Shaped like com.xxx.yyy.zzz, divided by dots */ public static Set<Class<?>> getClazz(String packageName) { // Recursion boolean isRecursion = true; // Define variables, save class file Set<Class<?>> clazz = new LinkedHashSet<Class<?>>(); char dot = '.'; char sprit = '/'; try { // Get the ContextClassLoader class loader according to the current thread. Note: the conversion of separator // The resource defined by the getResources method is a '/' separator Enumeration<URL> resources = Thread.currentThread().getContextClassLoader() .getResources(packageName.replace(dot, sprit)); // Ergodic enumeration while (resources.hasMoreElements()) { URL url = resources.nextElement(); // url:file:/E:/03.WorkSpaceToNew/soldier-openservice/target/classes/com/chuyutech/rssp/openservice/common/db/dao System.out.println("url:" + url.toString()); // Get agreement name String protocol = url.getProtocol(); // If it is a File type, the next step is the operation of the File class if (protocol.equals("file")) { // Decoding URLs using a specific encoding scheme String packagePath = URLDecoder.decode(url.getFile(), "UTF-8"); // Call method to get file recursively getClazzFromPath(packageName, packagePath, isRecursion, clazz); } } } catch (IOException e) { e.printStackTrace(); } return clazz; } /** * Get class file in file * * @param packageName:Package name; * packagePath:File path; isRecursion: recursion or not */ public static void getClazzFromPath(String packageName, String packagePath, boolean isRecursion, Set<Class<?>> clazz) { char dot = '.'; // Get File object based on pathname File file = new File(packagePath); if (!file.exists() || !file.isDirectory()) { return; } // List all files as an array of files File[] files = file.listFiles(new FileFilter() { // Anonymous inner class overrides FIleFilter @Override public boolean accept(File pathName) { // Custom filter rules if you can loop (including subdirectories) or end with. Class files (compiled java class files) return ((isRecursion && pathName.isDirectory()) || pathName.getName().endsWith(".class")); } }); // Traversing files for (File destFile : files) { // Continue scanning if directory if (destFile.isDirectory()) { getClazzFromPath(packageName + dot + destFile.getName(), destFile.getAbsolutePath(), isRecursion, clazz); } else { // If the java class file is removed after compilation, only the class name will be left String fileName = destFile.getName().substring(0, destFile.getName().lastIndexOf(dot)); // Add to collection to load class with full package name + ". + filename try { // Class<?> forName = Class.forName(packageName + dot + // Classname; this method initializes the static static code block of the loaded class Class<?> loadClass = Thread.currentThread().getContextClassLoader() .loadClass(packageName + dot + fileName); clazz.add(loadClass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } public static void main(String[] args) { String packageName = "com.chuyutech.rssp.openservice.common.db.dao"; Set<Class<?>> clazz = getClazz(packageName); System.out.println(clazz.size()); for (Class<?> class1 : clazz) { System.out.println(class1.getName()); } } }
3. summary:
3.1: general logic of implementation:
Get the ContextClassLoader class loader according to the current thread, and get the URL corresponding to the package name through the getResources(String name) method of the class loader
Get the absolute path through the URL, and use java.io.listFiles(FileFilter filter) of the File class to list all files or directories
Recursively call the file or directory obtained in the previous step, and finally use Thread.currentThread().getContextClassLoader()
. loadClass(className) gets the Class object and saves it to the set collection
3.2: Note:
Conversion of separator: the resource defined by getResources method is' / 'separator
4. Result printing:
---------------------over-----------------------