工具-----Java 扫描指定包下类 (包括jar包中的java类)

Java 扫描指定包下类  (包括jar包中的java类)

在某些场景中,我们需要得到某个包名下面所有的类,不仅仅是我们自己在写的包下面java类还有一些jar包(一些第三方提供的jar包里的类,一些是自己写的类)可以看下图,其结构如此:

比如我们想得到PackageScanner.java这个类

执行这个类

打印出的URL即目前的包的位置的一串字符串,其中replace方法时为了将其变成路径的表示形式

得到file文件路径

有两种,一种是文件夹即目录,一种是文件比如.class文件

Filed.isFile() 可以判断是否为文件。Filed.isDirectory可以判断是否为目录, 但如果是目录但进入目录后还是目录,如上图文件中com->HTT->scanner则需不断判断,如此可用递归处理。

执行递归直至不是文件即是.class文件,再去处理(里面的方法时自己写的,读者可按照自己想要去怎么用去写相应的代码)

jar包处理方法与此相似,下面贴出完整代码

package com.HTT.scanner;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URI;
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);
	
	private void dealClassFile(String rootPackage, File curFile) {
//        以下为我自己的处理.class方式
		String fileName = curFile.getName();
		if (fileName.endsWith(".class")) {
			fileName = fileName.replaceAll(".class", "");
			try {
				System.out.println("...  " + rootPackage + "." + fileName);
				Class<?> klass = Class.forName(rootPackage + "." + fileName);
				dealClass(klass);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void dealDirectory(String rootPackage, File curFile) {
//           若为目录则继续处理目录下面的目录和.class文件
		File[] fileList = curFile.listFiles();
		
		for (File file : fileList) {
			if (file.isDirectory()) {
				rootPackage = rootPackage + '.' + file.getName();
				System.out.println("00  " + rootPackage);
			//按照文件处理
				dealDirectory(rootPackage, file);
			} else if (file.isFile()) {
			//按照.class处理
				dealClassFile(rootPackage, file);
			}
		} 
	}
	
	private void dealJarPackage(URL url) {
		try {
//        得到路径
			JarURLConnection connection = (JarURLConnection) url.openConnection();
			JarFile jarFile = connection.getJarFile();
//        循环执行看是否有实体的存在
			Enumeration<JarEntry> jarEntries = jarFile.entries();
			while (jarEntries.hasMoreElements()) {
				JarEntry jar = jarEntries.nextElement();
//                                若不是.class文件或者是目录则不处理
//                                因为实体是一个个的比如这样的
                                    com/
                                    com/google/
                                    com/google/gson/
                                    com/google/gson/annotations/
                                    com/google/gson/internal/
                                    com/google/gson/internal/bind/
                                    com/google/gson/internal/bind/util/
//                                会将一个个列举出来
				if(jar.isDirectory() || !jar.getName().endsWith(".class")) {
					continue;
				}
//                                此处为小编我自己的处理
				String jarName = jar.getName();
				jarName = jarName.replace(".class", "");
				jarName = jarName.replace("/", ".");
				
				try {
					System.out.println(jarName);
					Class<?> klass = Class.forName(jarName);
					dealClass(klass);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void packageScanner(String packageName) {
		String rootPacksge = packageName;
		System.out.println("packageName : " + packageName);
		packageName = packageName.replace(".", "/");
		System.out.println("packageName : " + packageName);
		URL url = Thread.currentThread().getContextClassLoader().getResource(packageName);
		System.out.println("URL : " + url);
//判断协议名称是不是file,如果是file 则按照文件路径处理否则按照jar处理
		if (url.getProtocol().equals("file")) {
			URI uri;
			try {
				uri = url.toURI();
				File root = new File(uri);
				dealDirectory(rootPacksge, root);
			} catch (URISyntaxException e) {
				e.printStackTrace();
			}
		} else {
			dealJarPackage(url);
		}
	}
}
package com.HTT.scanner;

import java.net.URL;

public class Test {

	public static void main(String[] args) {

		new PackageScanner() {
		
		@Override
		public void dealClass(Class<?> klass) {
			
		}
		}.packageScanner("com.HTT.scanner");
	}

}

其中dealclass是抽象方法,当要使用此类时需实现自己处理方式。

执行结果如下:

大家可能会觉得我写成这样麻烦,实则是体现了做一个工具的思想,以后这个类就可以拿到以后直接用,实例化后在抽象方法中写上自己要如何处理这个类的代码即可,而不是简简单单的写一个一次性的代码。

如果觉得有什么问题可以在下面评论哦,

猜你喜欢

转载自blog.csdn.net/baidu_41922630/article/details/101308092