JAVA简易类加载器
2017-09-30 本文已影响31人
AmeeLove
package com.ghg.smartframework.helper;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 类加载器
*
* @author Administrator
*
*/
public class ClassHelper {
private static Logger logger = LoggerFactory.getLogger(ClassHelper.class);
/**
* 获取类加载器
*
* @return
*/
public static ClassLoader getClassLoad() {
return Thread.currentThread().getContextClassLoader();
}
/**
* 加载指定类
*
* @param className
* 全路径
* @param isInitialized
* 是否执行静态代码块, false不执行 true反之
* @return
*/
public static Class<?> loadClass(String className, boolean isInitialized) {
Class<?> clz = null;
try {
clz = Class.forName(className, isInitialized, getClassLoad());
} catch (ClassNotFoundException e) {
e.printStackTrace();
logger.debug("loadClass fail {} --{} ", className, isInitialized);
}
return clz;
}
/**
* 获取指定包下的所有类
*
* @param packageName
* @return
*/
public static Set<Class<?>> getClassSet(String packageName) {
Set<Class<?>> classSet = new HashSet<Class<?>>();
try {
// 获取资源地址
Enumeration<URL> urls = getClassLoad().getResources(packageName.replace(".", "/"));
// 循环
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
// 判断是否为空
if (url != null) {
// 获取协议判断是否是文件
String protocol = url.getProtocol();
if (protocol.equals("file")) {
// 替换路径中的url编码 %20 unicode的编码,防止字符在传输中丢失
String packagePath = url.getPath().replaceAll("%20", "");
// 添加
addClass(classSet, packagePath, packageName);
} else if (protocol.equals("jar")) {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
if (jarURLConnection != null) {
JarFile jarFile = jarURLConnection.getJarFile();
// 判断
if (jarFile != null) {
// 获取jar中的所有实体
Enumeration<JarEntry> jarEntries = jarFile.entries();
// 循环
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
// 判断
String jarEntryName = jarEntry.getName();
// 判断是不中class
if (jarEntryName.endsWith(".class")) {
// 获取类的全路径,把/替换为.
String className = jarEntryName.substring(0, jarEntryName.lastIndexOf("."))
.replace("/", ".");
// 添加
doAddClass(classSet, className);
}
}
}
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
logger.debug(" get classSet fail");
}
return classSet;
}
/**
* 添加
*
* @param classSet
* @param packagePath
* @param packageName
*/
public static void addClass(Set<Class<?>> classSet, String packagePath, String packageName) {
File[] files = new File(packagePath).listFiles(new FileFilter() {
// 过滤
@Override
public boolean accept(File file) {
return (file.isFile() && file.getName().endsWith(".class") || file.isDirectory());
}
});
if (files == null) {
return;
}
for (File file : files) {
String fileName = file.getName();
// 是否为文件
if (file.isFile()) {
// 获取类名称
String className = fileName.substring(0, fileName.lastIndexOf("."));
if (StringHelper.isNotEmpty(packageName)) {
className = packageName + "." + className;
}
doAddClass(classSet, className);
} else {
// 不是文件
String subPackagePath = fileName;
if (StringHelper.isNotEmpty(packagePath)) {
// 拼接路径包名加上子包名
subPackagePath = packagePath + "/" + subPackagePath;
}
String subPackageName = fileName;
if (StringHelper.isNotEmpty(packageName)) {
subPackageName = packageName + "." + subPackageName;
}
addClass(classSet, subPackagePath, subPackageName);
}
}
}
/**
* 添加
*
* @param classSet
* @param className
*/
public static void doAddClass(Set<Class<?>> classSet, String className) {
Class<?> cls = loadClass(className, false);
classSet.add(cls);
}
public static void main(String[] args) {
String packageName = "com.ghg.smartframework";
// Class<?> class1 = loadClass("com.ghg.smartframework.Test", false);
Set<Class<?>> classSet = getClassSet(packageName);
System.out.println(" classSet " + classSet.size());
for (Class<?> cls : classSet) {
System.out.println(" cls " + cls.getName() + " " + cls.getSimpleName());
}
}
}