Java实现类加载器,加载指定包名下的所有类

package com.newframework.utils;


import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;


import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 构造类加载机制,加载指定包名下的所有类信息
 * @author kaixinnongchang208
 *
 */
public class ClassUtil {

private static Logger logger = LoggerFactory.getLogger(ClassUtil.class);

private static final String FILE_TYPE = "file";

private static final String JAR_TYPE = "jar";

/**
* 获取当前线程加载器
* @return
*/
public static ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}

/**
* 加载类
* @param className
* @param isInitialized
* @return
*/
public static Class loadClass(String className, boolean isInitialized) {
Class cls = null;
try {
cls = Class.forName(className, isInitialized, getClassLoader());
} catch (ClassNotFoundException e) {
logger.error("load class failure", e); 
throw new RuntimeException();
}
return cls;
}

/**
* 获取指定包下的所有类对象
* @param packageName
* @return
*/
public static Set> getClassSet(String packageName) {
Set> classSets = new HashSet>(); // 将类信息保存到集合中存储
try {
// 将包全名称替换为文件路径
Enumeration urls = getClassLoader().getResources(packageName.replace(".", "/"));
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
// 协议名称,判断文件类型
String protocol = url.getProtocol();
// 多种文件类型判断,只需增加if即可
if (FILE_TYPE.equals(protocol)) {
String basePath = url.getPath().replace("%20", ""); // 去掉空格
addClass(classSets, basePath, packageName); //获取类全路径,并反射加载类
} else if (JAR_TYPE.equals(protocol)) {}
}
} catch (Exception e) {
logger.error("get class set failure", e);
throw new RuntimeException();
}
return classSets;
}

/**
* 扫描文件目录,获取子目录的文件,并执行反射获取类文件信息
* @param classSets
* @param basePath
* @param packageName
*/
public static void addClass(Set> classSets, String basePath, String packageName) {
// 获取子目录
File[] files = new File(basePath).listFiles(new FileFilter() {
public boolean accept(File file) {
// 过滤文件,必须为文件且以.class结尾,或者是文件目录
return ((file.isFile() && file.getName().endsWith(".class")) || (file.isDirectory()));
}
});
// 遍历获取文件信息
for (File file : files) {
String fileName = file.getName();
// 如果为文件
if (file.isFile()) {
String className = fileName.substring(0, fileName.lastIndexOf("."));
if (StringUtils.isNotEmpty(className)) {
className = packageName + "." + className;
}
doAddClass(classSets, className);
} else {
// 获取文件名称,该文件为目录
String subPath = fileName;
if (StringUtils.isNotEmpty(subPath)) {
subPath = packageName + "/" + subPath;
}
// 获取包名
String subPackage = packageName;
if (StringUtils.isNotEmpty(subPackage)) {
subPackage = packageName + "." + fileName;
}
// 递归遍历文件信息
addClass(classSets, subPath, subPackage);
}
}
}

/**
* 将反射对象添加到集合中
* @param classSets
* @param className
*/
private static void doAddClass(Set> classSets, String className) {
Class cls = loadClass(className, false);
classSets.add(cls);
}
}

你可能感兴趣的:(springMVC)