Java包扫描(工具)

这篇文章主要介绍一个包扫描工具。
包扫描工具的功能:通过给定一个包名称,该工具会根据给定的包名称自动扫描并得到该包下的所有文件,并通过抽象方法将该文件进行处理。这里的包主要分为普通包和Jar包,通过Protocol(协议)来判断是普通包还是Jar包,然后分别处理,将处理后得到的类作为抽象方法的参数交由外部处理该类。

下面我们来看一下具体实现过程:

public abstract class PackageScanner {
	//无参构造方法
	public PackageScanner() {
	}
	//抽象方法,将包扫描得到的类交给外部处理(用户处理)
	public abstract void dealClass(Class<?> klass);
	//处理普通包
	private void dealPackage(File curFile, String packageName) {
		//得到当前文件夹下的所有文件或子文件夹
		File[] files = curFile.listFiles();
		//对所得到的文件或子文件夹进行遍历
		for (File file : files) {
			//判断是否为文件,如果是文件,则进一步处理;反之如果是文件夹则继续扫描直到是文件
			if (file.isFile()) {
				String fileName = file.getName();
				/判断该文件是否是.class文件,若不是不做处理
				if (!fileName.endsWith(".class")) {
					continue;
				}
				//例如:Gson.class --> Gson
				fileName = fileName.replace(".class", "");
				//得到类名(如:com.google.gson.Gson)
				String className = packageName + "." + fileName;
				try {
					Class<?> klass = Class.forName(className);
					dealClass(klass);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			} else {
				//这里运用了递归,如果是文件夹就一直扫描,直到扫描到文件
				dealPackage(file, packageName + "." + file.getName());
			}	
		}
	}
	//处理Jar包
	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();
				//如果该文件是目录或者不是以.class结尾,则不做处理
				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();
		}
	}
	//给定包名称,开始包扫描
	public void scanPackage(String packageName) {
		//得到当前线程的类加载器
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		//将包名称转换成路径名称
		String pathName = packageName.replace(".", "/");
		try {
			//由类加载器得到URL的枚举
			Enumeration<URL> urls = classLoader.getResources(pathName);
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				//得到URL的协议并判断是否为Jar包
				if (url.getProtocol().equals("jar")) {
					dealJar(url);//如果是,处理Jar包
				} else {
					//反之处理普通包
					try {
						//根据URL得到当前目录(文件夹)
						File curFile = new File(url.toURI());
						dealPackage(curFile, packageName);
					} catch (URISyntaxException e) {
						e.printStackTrace();
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

下面我们来测试一下,扫描一下Jar包,这里我只截取了一部分:
在这里插入图片描述
测试代码如下

public class Test {
	
	public static void main(String[] args) {
		new PackageScanner() {
			@Override
			public void dealClass(Class<?> klass) {
				if (klass.isPrimitive()
						|| klass.isAnnotation()
						|| klass.isInterface()
						|| klass.isEnum()
						|| klass.isArray()) {
					return;
				}
				System.out.println(klass.getName());
			}
		}.scanPackage("com.google.gson");//这里扫描的是Jar包
	}

}

测试结果(只贴出来了一部分):

com.google.gson.DefaultDateTypeAdapter
com.google.gson.FieldAttributes
com.google.gson.FieldNamingPolicy$1
com.google.gson.FieldNamingPolicy$2
com.google.gson.FieldNamingPolicy$3
com.google.gson.FieldNamingPolicy$4
com.google.gson.FieldNamingPolicy$5
com.google.gson.Gson$1
com.google.gson.Gson$2
com.google.gson.Gson$3
com.google.gson.Gson$4
com.google.gson.Gson$5
com.google.gson.Gson$6
com.google.gson.Gson$FutureTypeAdapter

由此可以看出,这个包扫描工具是成功的,以后可以打成jar包使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值