包及jar包扫描

public PackageScanner() {
}

//扫描包
private void scanFile(File currentFile, String packageName) {
	//File[] fileList = file.listFiles();
	//得到该文件夹下的所有 类+子文件夹的名称
	//此处list应为扫描包下的所有类的nameList,所以不应该有文件名称
	//所以应该加一个文件过滤器
	File[] fileList = currentFile.listFiles(new FileFilter() {
		@Override
		public boolean accept(File pathname) {
			if(pathname.isDirectory()) {
				return true;
			}
			return pathname.getName().endsWith(".class");
		}
	});
	
	for(File f : fileList) {
		//如果是文件夹,递归处理
		if(f.isDirectory()) {
			scanFile(f, packageName + "." + f.getName());
		} else {
			String className = packageName + "." 
					+ f.getName().replace(".class", "");
			try {
				Class<?> klass = Class.forName(className);//得到类 
				//可以筛选类
				if(klass.isAnnotation()//是注解
						|| klass.isEnum()//是枚举
						|| klass.isInterface()//是接口
						|| klass.isPrimitive()) {//是基本类型
						continue;
						//这些类型我们不需要 所以不处理
				}
				dealClass(klass);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
}

//扫描jar包
private void scanJarPackage(URL url) throws IOException {
	//连接jar文件的一个入口连接定位
	JarURLConnection urlConnection = (JarURLConnection) url.openConnection();	
	JarFile jarFile = urlConnection.getJarFile();//得到jar文件
	Enumeration<JarEntry> jarEntries = jarFile.entries();
	//读取jar文件下的内容
	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 packageScanner(String packageName) {
	String packageRelativePath = packageName.replace('.', '/');
	
	ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
	//线程.得到当前线程.得到类加载器(当前线程即这个test,但不能直接用test. ,
	//因为java是多线程的,可能不会得到这个test)
	try {
		Enumeration<URL> resource 
			= classLoader.getResources(packageRelativePath);
		//一个枚举类型集合
		while(resource.hasMoreElements()) {
			URL url = resource.nextElement();
			if(url.getProtocol().equals("jar")) { 
				scanJarPackage(url);
			} else {
				File file = new File(url.toURI());
				if(!file.exists()) {//file不存在
					continue;
				}
				//得到要扫描的包(即文件夹) 此处为classes
				scanFile(file, packageName);
			}
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

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

public static void main(String[] args) {
	String packageName = "com.zty.classes";
	//path如果是以 / 开头,就从classpath中去找
	//(classpath是bin目录或是target的classes目录)
	//如果不以/开头,就以当前类的位置开始找
			
	 new PackageScanner(){
		@Override
		public void dealClass(Class<?> klass) {
			System.out.println(klass.getName());
		}
	}.packageScanner(packageName);
}

扫描的包为:
在这里插入图片描述

运行结果:
在这里插入图片描述

剔除了枚举、接口、注解及基本类型之后的结果。

猜你喜欢

转载自blog.csdn.net/A_BCDEF_/article/details/82940539