从零写一个具有IOC-AOP-MVC功能的框架---学习笔记---03.获取指定包下的类---ClassUtil工具类的编写

1. 本节需要完成的任务

  1. 完成对指定包下以及其子包下所有类的获取的工具类的编写

2. 项目配置

2.1 进行pom文件的相关配置

在这里插入图片描述

2.2 安装lombok插件

在这里插入图片描述

2.3 指定maven-compiler-plugin插件的相关配置

在这里插入图片描述

3. ClassUtil类中相关方法的编写

3.1 需要完成的代码如下

package com.wuyiccc.helloframework.util;

import lombok.extern.slf4j.Slf4j;

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

/**
 * @author wuyiccc
 * @date 2020/7/13 7:26
 * 岂曰无衣,与子同袍~
 */
@Slf4j
public class ClassUtil {

    public static final String FILE_PROTOCOL = "file";

    /**
     * 根据传入的包名,获取该包以及其子包下所有的类
     * @param packageName
     * @return
     */
    public static Set<Class<?>> extractPackageClass(String packageName) {


        // 获取当前线程的类加载器
        ClassLoader classLoader = getClassLoader();
        // 通过类加载器获取到加载的资源
        URL url = classLoader.getResource(packageName.replace(".", "/")); // URL格式 类似于 file:/文件在本机上的绝对路径

        if (url == null) {
            log.warn("unable to retrieve anything from package: " + packageName);
            return null;
        }

        // 依据不同的资源,采用不同的方式获取资源的集合
        Set<Class<?>> classSet = null;

        // 过滤出文件类型的资源
        if (url.getProtocol().equalsIgnoreCase(FILE_PROTOCOL)) {
            classSet = new HashSet<>();
            File packageDirectory = new File(url.getPath());
            extractClassFile(classSet, packageDirectory, packageName);
        }
        return classSet;

    }

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


    private static void extractClassFile(Set<Class<?>> emptyClassSet, File fileSource, String packageName) {

        if (!fileSource.isDirectory()) { // 如果不是目录,直接返回
            return;
        }

        // 如果是文件夹,那么将该文件夹下的.class文件放入emptyClassSet中
        File[] files = fileSource.listFiles(new FileFilter() { // listFile 只会返回该文件夹下的文件及文件夹,不会返回子文件夹下的内容
            @Override
            public boolean accept(File file) {
                if (file.isDirectory()) {
                    return true;
                } else {

                    // 如果不是文件夹,就把.class文件放入类集合中
                    String absoluteFilePath = file.getAbsolutePath();
                    if (absoluteFilePath.endsWith(".class")) {
                        addToClassSet(absoluteFilePath);
                    }
                }

                return false;

            }

            private void addToClassSet(String absoluteFilePath) {

                // 从绝对路径下获取类名
                absoluteFilePath = absoluteFilePath.replace(File.separator, ".");
                String className = absoluteFilePath.substring(absoluteFilePath.indexOf(packageName));
                className = className.substring(0, className.lastIndexOf("."));// [)

                // 通过反射获取Class对象
                Class targetClass = loadClass(className);
                emptyClassSet.add(targetClass);
            }
        });

        if (files != null) {
            for (File f : files) {
                extractClassFile(emptyClassSet, f, packageName);
            }
        }
    }

    public static Class<?> loadClass(String className) {
        try {
            return Class.forName(className);
        } catch (ClassNotFoundException e) {
            log.error("load class error");
            throw new RuntimeException(e);
        }
    }

}

3.2 需要完成的相关代码的讲解如下:

3.2.1 extractPackageClass方法解读:

在这里插入图片描述

3.2.2 getClassLoader方法解读

在这里插入图片描述

3.2.3 extractClassFile方法解读

在这里插入图片描述

3.2.4 loadClass方法解读

在这里插入图片描述

github地址:https://github.com/wuyiccc/helloframework

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值