【JAVA】包扫描及jar包扫描工具的设计

xiaoxiao2025-10-08  16

包扫描的作用:

按指定包路径和要求扫描出符合条件的类,并反射出它们的类类型,在此基础上进行各种操作。

如:扫描包内含有注解的类并进行处理等。

我们的需求是对普通类进行处理的,所以在扫描时应当排除接口、枚举、注解、以及八大基本类型。

此外,在实际应用时,针对在扫描出类后所要进行的,不能在编写工具时期所能确定的操作,我们给出一个抽象方法,在扫描出每个符合条件的类后调用这个抽象方法。要求用户在实际应用时实现此方法。

public abstract void dealClass(Class<?> klass);

普通包扫描:

 

private void packageScan(String pathname, File currentFile) { //File类的对象表示一个文件或文件夹 //FileFilter起到一个文件过滤器的作用,其中的accept()方法体现出了筛选过程 File[] fileList = currentFile.listFiles(new FileFilter() { //只筛选出“.class”和文件夹的File对象 @Override public boolean accept(File pathname) { if(pathname.isDirectory()) { return true; } return pathname.getName().endsWith(".class"); } }); for(File file : fileList) { String fileName = file.getName(); if(file.isDirectory()) { //构建出当前文件夹所表示的包路径,递归扫描 packageScan(pathname + "." + file.getName(), file); } else { //构建出类名称并进行反射,进一步筛选 String className = pathname + "." + fileName.replace(".class", ""); try { Class<?> klass = Class.forName(className); if(klass.isAnnotation() || klass.isInterface() || klass.isEnum() || klass.isPrimitive()) { continue; } dealClass(klass);//未来的处理 } catch (ClassNotFoundException e) { e.printStackTrace(); } } } }

Jar包扫描:

至于jar包扫描,需要用到一些前人所提供的工具,初学者看到也不必惊慌,拿来用就是了。

private void scanPackage(URL url) throws IOException { JarURLConnection urlConnection = (JarURLConnection) url.openConnection(); JarFile jarFile = urlConnection.getJarFile(); Enumeration<JarEntry> jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarName = jarEntry.getName(); if (jarEntry.isDirectory() || !jarName.endsWith(".class")) { continue; } String className = jarName.replace(".class", "").replaceAll("/", "."); try { Class<?> klass = Class.forName(className); if (klass.isAnnotation() || klass.isInterface() || klass.isEnum() || klass.isPrimitive()) { continue; } dealClass(klass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }

综合:

public void packageScan(String pathname) { String opperPathname = pathname.replace('.', '/'); //得到当前上下文的类加载器(动态加载类到JVM中) ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { Enumeration<URL> resources = classLoader.getResources(opperPathname); while(resources.hasMoreElements()) { URL url = resources.nextElement(); if(url.getProtocol().equals("jar")) { //扫描jar包 scanPackage(url); } else { //普通包扫描 File file = new File(url.toURI()); if (!file.exists()) { continue; } packageScan(pathname, file); } } } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } }

这样包扫描的基本功能就完成了。在此基础上我们在给上几种方法的重载,让我们的工具能适应的情况多一些。

public void packageScan(Class<?> klass) { packageScan(klass.getPackage().getName()); } public void packageScan(Class<?>[] classes) { for(Class<?> klass : classes) { packageScan(klass); } } public void packageScan(String[] packages) { for(String packageName : packages) { packageScan(packageName); } }

 

转载请注明出处。

转载请注明原文地址: https://www.6miu.com/read-5037548.html

最新回复(0)