工具包中的小工具------包扫描(包括jar包)

今天的工具功能是包扫描,只需要调用指定方法,输入想要查询的包名称,就可以自动查询得到该路径下所有的类(包括jar包),该工具实现了一个抽象方法供使用者使用,用这个方法可以去筛选该包下的类达到自己的目的。

package com.mec.mpring.core;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public abstract class PackageScanner {
	
	public PackageScanner() {
	}
	
	//因为扫描到的类的相关具体操作不是本工具需要完成的,
	//因此给一个抽象方法,具体操作由工具使用者完成。
	//用这个方法可以去筛选使用者需要扫描的包下的类达到自己的目的。
	public abstract void dealClass(Class<?> klass);
	
	//处理普通包,注意这里面有递归,如果找到类就调用dealClass方法,若包下还有包,那么就要继续调用自身进行扫描,知道扫描结束。
	private void dealPackage(File cur, String packageName) {
		File[] files = cur.listFiles();
		for (File file : files) {
			if (file.isFile()) {
				String fileName = file.getName();
				if (!fileName.endsWith(".class")) {
					continue;
				}
				fileName = fileName.replace(".class", "");
				String className = packageName + "." + fileName;
				try {
					Class<?> klass = Class.forName(className);
					dealClass(klass);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			} else {
				dealPackage(file, packageName + "." + file.getName());
			}
		}
	}
	
	//处理jar包,需要注意的是,如果要扫描自己写的jar包,那么导出jar包时必须勾选 add directory entries选项,否则扫描失败。
	private void dealJar(URL url) {
		try {
			JarURLConnection connection = (JarURLConnection) url.openConnection();
			JarFile jarFile = connection.getJarFile();
			Enumeration<JarEntry> entryList = jarFile.entries();
			while (entryList.hasMoreElements()) {
				JarEntry jarEntry = entryList.nextElement();
				if (jarEntry.isDirectory() || !jarEntry.getName().endsWith(".class")) {
					continue;
				}
				String className = jarEntry.getName();
				className = className.replace(".class", "");
				className = className.replace('/', '.');
				try {
					Class<?> klass = Class.forName(className);
					dealClass(klass);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//这个方法是使用者需要调用的方法,它可以实现普通包和jar包的扫描。使用者只需提供包路径(例如:com.mec.util)即可。
	public void scanPackage(String packageName) {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		String pathName = packageName.replace('.', '/');
		try {
			synchronized (pathName) {
				
			}
			Enumeration<URL> urls = classLoader.getResources(pathName);
			System.out.println("urls" +"   " + urls);
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				System.out.println("url" +"   "+ url);
				System.out.println("url.getProtocol()" +"   " + url.getProtocol());
				if (url.getProtocol().equals("jar")) {
					dealJar(url);
				} else {
					try {
						File curFile = new File(url.toURI());
						dealPackage(curFile, packageName);
					} catch (URISyntaxException e) {
						e.printStackTrace();
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

如上图所示:右边是代码示例。我扫描的包是com.mec.rmi,所以工具将该目录下所有类都输出了,用粉色圈出来的是RMIServer的内部类,也输出了。
今天的工具就介绍到这里吧。欢迎批评指正~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值