文章目录

  • 提取标记对象
  • 编写获取某个包下的类的集合工具类


提取标记对象

实现思路:

  1. 指定对象范围, 获取范围内的所有类
  2. 遍历所有类, 获取被注解标记的类并加载进容器里.

编写获取某个包下的类的集合工具类

获取某个包下的类集合 :

1. 获取到类加载器:

目的: 获取项目发布的实际路径 . 不同的系统表示路径的方法不同. 如果是war或jar包就找不到jar包.

类加载器: ClassLoader

ClassLoader从字节码文件中读取字节码, 并转换为java.lang.Class一个类实例, 并存储在jvm的内存中. 每一个这样的实例, 用来表示一个java类, 之后通过反射创建出此实例的对象.

ClassLoader的作用即如下的两点:

根据一个指定的类名称, 找到或生成其对应的字节码

加载Java应用程序所需的资源, 例如配置文件等.

java 读取和jar相同路径的文件 java读取jar包里的文件_加载


2. 通过类加载器获取到加载的资源信息

3. 根据不同的资源类型, 采取不同的方式获取资源的集合

获取当前线程的ClassLoader, 方法如下

/**
     *  获取当前的ClassLoader
     *   程序是通过线程执行的, 获取当前执行的方法的线程, 便能通过线程属的类加载器获取程序资源信息
     *
     * @return
     */
    public static ClassLoader getClassLoader(){
        return Thread.currentThread().getContextClassLoader();
    }

getContextClassLoader 源码如下,

java 读取和jar相同路径的文件 java读取jar包里的文件_jar包_02


ClassLoader 对象的源码中, 有getResource方法如下:

该方法主要是返回一个URL, 统一资源定位符.

java 读取和jar相同路径的文件 java读取jar包里的文件_java 读取和jar相同路径的文件_03


统一资源定位符:

URL 是用于获取某个资源的唯一地址:

通过获取java.net.URL 实例获取协议名称, 资源名称, 等信息 .

如下是一个URL包含的信息. 包含协议 域名 端口 路径请求参数等.

主要是 协议和 路径.

java 读取和jar相同路径的文件 java读取jar包里的文件_加载_04


URL 类中 有getProtocol 获取协议的方法, getPath 来获取路径 . 此路径是绝对路径, 如果是文件, 文件名也在其中.

java 读取和jar相同路径的文件 java读取jar包里的文件_jar包_05


java 读取和jar相同路径的文件 java读取jar包里的文件_加载_06

获取某个包下的类集合 :

/**
     *  获取某个包下的类集合 :
     *   1. 获取到类加载器:
     *        目的:   获取项目发布的实际路径 . 不同的系统表示路径的方法不同. 如果是war或jar包就找不到jar包.
     *        类加载器: ClassLoader
     *
     *   2. 通过类加载器获取到加载的资源信息
     *   3. 根据不同的资源类型, 采取不同的方式获取资源的集合
     * @param packageName 包名
     * @return 类集合
     */
    public static Set<Class<?>> extractPackageClass(String packageName){
        // 1. 获取到类加载器
        ClassLoader classLoader = getClassLoader();
        // 2. 通过类加载器获取到加载的资源信息
        URL url = classLoader.getResource(packageName.replace(".", "/"));
        if (url == null) {
            log.error(" 无法获取到资源, 从此包中 : " + packageName);
            return  null;
        }

        return null;
    }