包扫描工具:
1.普通包扫描:
// 需要包的路径和包名称
private void packageScanner(String packagePath, String packageName) {
// 通过包路径得到当前文件
File currentFile = new File(packagePath);
if(!currentFile.exists()) {
return;
}
// 得到当前文件下的所有文件
// 通过文件过滤器接口得到所有的目录类型的文件
File[] listFile = currentFile.listFiles(new FileFilter() {
// 若当前文件是目录则返回true,否则就是最终的class文件
// java内部最终执行的是对源码预编译的字节码文件,是class文件
@Override
public boolean accept(File pathname) {
if (currentFile.isDirectory()) {
return true;
}
return pathname.getName().endsWith(".class");
}
});
// 递归遍历,扫描所有的目录,并更新当前目录的路径
for (File file : listFile) {
if (file.isDirectory()) {
packageScanner(file.getAbsolutePath(),
packageName + "." + file.getName());
} else {
// 扫描到类时,去除后缀,得到该类全名
String fileName = file.getName();
int index = fileName.indexOf(".class");
fileName = fileName.substring(0, index);
String className = packageName + "." + fileName;
try {
Class<?> klass = Class.forName(className);
dealClass(klass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
2.jar包扫描:
// URL 是统一资源定位符。
// 对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,
//是互联网上标准资源的地址。
//互联网上的每个文件都有一个唯一的URL,
//它包含的信息指出文件的位置以及浏览器应该怎么处理它。
private void packageScanner(URL url) {
try {
JarURLConnection jarURLConnection =
(JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
if (jarEntry.isDirectory() || !jarEntry.getName().endsWith(".class")) {
continue;
}
String className = jarEntry.getName();
int index = className.indexOf(".class");
className = className.substring(0, index).replace("/", ".");
try {
Class<?> klass = Class.forName(className);
dealClass(klass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
3.对包的类型判断,该方法由外部调用(上述两个方法仅为当前方法使用)。
public void packageScan(String rootPackage) {
// 类加载
this.classLoder = Thread.currentThread().getContextClassLoader();
Enumeration<URL> urls;
try {
urls = classLoder.getResources(rootPackage.replace(".", "/"));
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
// 获取协议名称
String jarPortocol = url.getProtocol();
// 根据URL判断其属性
if (jarPortocol.equals("file")) {
// 抽象出路径名
try {
File file = new File(url.toURI());
packageScanner(file.getAbsolutePath(), rootPackage);
} catch (URISyntaxException e) {
e.printStackTrace();
}
} else if (jarPortocol.equals("jar")) {
packageScanner(url);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
4.该工具类为抽象类,将得到的类交由用户处理。并且还需添加根据类来对该类所在包的扫描的方法。
// 将扫描出来的类由用户处理
public abstract void dealClass(Class<?> klass);
// 通过类来扫描类所在的包
public void packageScan(Class<?> klass) {
packageScan(klass.getPackage().getName());
}
完整代码:
package com.chy.package_scan.core;
import java.io.File;
import java.io.FileFilter;
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 PackageScan {
private ClassLoader classLoder;
public PackageScan() {
}
public abstract void dealClass(Class<?> klass);
private void packageScan(String packagePath, String packageName) {
File currentFile = new File(packagePath);
if(!currentFile.exists()) {
return;
}
File[] listFile = currentFile.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (currentFile.isDirectory()) {
return true;
}
return pathname.getName().endsWith(".class");
}
});
for (File file : listFile) {
if (file.isDirectory()) {
packageScan(file.getAbsolutePath(),
packageName + "." + file.getName());
} else {
String fileName = file.getName();
int index = fileName.indexOf(".class");
fileName = fileName.substring(0, index);
String className = packageName + "." + fileName;
try {
Class<?> klass = Class.forName(className);
dealClass(klass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
private void packageScan(URL url) {
try {
JarURLConnection jarURLConnection =
(JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
if (jarEntry.isDirectory() || !jarEntry.getName().endsWith(".class")) {
continue;
}
String className = jarEntry.getName();
int index = className.indexOf(".class");
className = className.substring(0, index).replace("/", ".");
try {
Class<?> klass = Class.forName(className);
dealClass(klass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void packageScan(Class<?> klass) {
packageScan(klass.getPackage().getName());
}
public void packageScan(String rootPackage) {
this.classLoder = Thread.currentThread().getContextClassLoader();
Enumeration<URL> urls;
try {
urls = classLoder.getResources(rootPackage.replace(".", "/"));
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
String jarPortocol = url.getProtocol();
if (jarPortocol.equals("file")) {
try {
File file = new File(url.toURI());
packageScan(file.getAbsolutePath(), rootPackage);
} catch (URISyntaxException e) {
e.printStackTrace();
}
} else if (jarPortocol.equals("jar")) {
packageScan(url);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}