对于给定指定包名获取所有类

对于给定指定包名获取所有的类

对于一个IOC框架来说,这个功能是最基本,但是对于初学者来说确实不好来完成。接下来我会先贴代码,然后根据代码分析。

/**
 * 对于制定包名的加载类
 * author:Lizhao
 * Date:15/12/16
 * version:1.0
 *
 * @param pacckageName
 *
 * @return
 */
public static Set<Class<?>> getClassSet(String pacckageName) {
Set<Class<?>> classSet = new HashSet<Class<?>>();

try {

// 得到制定包名下面的资源
Enumeration<URL> urls = getClassloader().getResources(pacckageName.replace(".", "/"));

while (urls.hasMoreElements()) {

// url 格式file:/D:/eclipse/workspace/demo/WebContent/WEB-INF/classes/config/aaa.txt
URL url = urls.nextElement();

if (url != null) {
String protocol = url.getProtocol();// 返回协议 是file 还是 jar

if (protocol.equals("file")) {

// 20%是URL的空格,将其代替,SUN公司也说明了这是一个BUG
String packagePath = url.getPath().replaceAll("%20", " ");

addClass(classSet, packagePath, pacckageName);
}
else if(protocol.equals("jar")){
//如果是Jar则建立连接
JarURLConnection jarURLConnection= (JarURLConnection) url.openConnection();
if(jarURLConnection!=null){
//得到Jarfile对象
JarFile jarFile=jarURLConnection.getJarFile();
//如果jarFile不为空
if(jarFile!=null){
//得到jarw文件内的实体
Enumeration<JarEntry> jarEntries=jarFile.entries();
while (jarEntries.hasMoreElements()){//遍历实体
JarEntry jarEntry=jarEntries.nextElement();
//得到jar实体的名字 例如javax/crypto/SecretKey.class
String jarEntryName=jarEntry.getName();
if(jarEntryName.endsWith(".class")){
String className=jarEntryName.substring(0,jarEntryName.lastIndexOf(".")).replaceAll("/",".");
doAddClass(classSet,className);
}
}
}
}

}
}
}
} catch (IOException e) {
LOGGER.error("get class set failure",e);
 throw new RuntimeException(e);
}

return classSet;
}

/**
 *
 * author:Lizhao
 * Date:15/12/16
 * version:1.0
 *
 * @param classSet
 * @param packagePath
 * @param pacckageName
 */
private static void addClass(Set<Class<?>> classSet, String packagePath, String pacckageName) {
File[] files = new File(packagePath).listFiles(new FileFilter() {

// 目录过滤器,过滤class文件和文件夹
@Override
public boolean accept(File file) {
return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
}
});

for (File file : files) {
String fileName = file.getName();

if (file.isFile()) {

// 截取.class之前的部分
String className = fileName.substring(0, fileName.lastIndexOf("."));

if (StringUtil.isNotEmpty(pacckageName)) {

// 包名加类名
className = pacckageName + "." + className;
}

doAddClass(classSet, className);
} else {

// 如果是文件夹,就把路径和包名都相加,继续迭代
String subPackagePath = fileName;

if (StringUtil.isNotEmpty(packagePath)) {
subPackagePath = packagePath + "/" + subPackagePath;
}

String subPackageName = fileName;

if (StringUtil.isNotEmpty(pacckageName)) {
subPackageName = pacckageName + "." + subPackageName;
}
//执行添加类
addClass(classSet, subPackagePath, subPackageName);
}
}
}

/**
 * 添加类加载
 * author:Lizhao
 * Date:15/12/16
 * version:1.0
 *
 * @param classSet
 * @param className
 */
private static void doAddClass(Set<Class<?>> classSet, String className) {
Class<?> cls = loadClass(className, false);

classSet.add(cls);
}

  对于上面一些部分有详细地说明,接下来对代码逐一分析。

1.Set

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值