Java高级进阶:自定义ClassLoader

简介: 假如我们的类不在classpath下,而我们又想读取一个自定义的目录下的class,如果做呢?读取自定义目录的类示例读取c:/test/com/test.jdk/Key.class这个类。

假如我们的类不在classpath下,而我们又想读取一个自定义的目录下的class,如果做呢?

读取自定义目录的类

示例读取c:/test/com/test.jdk/Key.class这个类。

package com.test.jdk;

public class Key {
    private String key = "111111";
}

自定义ClassLoader

import org.apache.commons.io.IOUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class LocalClassLoader extends ClassLoader {

    private String path = "c:/test/";

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> cls = findLoadedClass(name);
        if (cls != null) {
            return cls;
        }

        if (!name.endsWith(".Key")) {
            return super.loadClass(name);
        }

        try {
            InputStream is = new FileInputStream(path + name.replace(".", "/") + ".class");
            byte[] bytes = IOUtils.toByteArray(is);
            return defineClass(name, bytes, 0, bytes.length);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return super.loadClass(name);
    }
}

开始读取类

public static void main(String[] args) {
    try {
        LocalClassLoader lcl = new LocalClassLoader();
        Class<?> cls = lcl.loadClass("com.test.jdk.Key");
        Field field = FieldUtils.getField(cls, "key", true);
        Object value = field.get(cls.newInstance());
        System.out.println(value);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

自定义类加载器正常加载到类,程序最后输出:111111

URLClassLoader

上面自定义一个类加载器来读取自定义的目录,其实可以直接使用URLClassLoader就能读取,它已经实现了路径下类的读取逻辑。

public static void main(String[] args) {
    try {
        URLClassLoader ucl = new URLClassLoader(new URL[]{new URL("c:/test/")});
        Class<?> cls = ucl.loadClass("com.test.jdk.Key");
        Field field = FieldUtils.getField(cls, "key", true);
        Object value = field.get(cls.newInstance());
        System.out.println(value);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

推荐阅读

什么是Spring Boot?
Spring Boot开启的2种方式
Spring Boot Starters启动器
Spring Boot定制启动图案
Spring Boot核心配置
Spring Boot功能实战
Spring Boot自动配置原理、实战
Spring Boot Runner启动器
Spring Boot - Profile不同环境配置

看完有没有收获?分享到朋友圈给更多的人吧。

相关文章
|
1月前
|
存储 Java 计算机视觉
Java代码居然可以做出如此高级的图片编辑系统
Java代码居然可以做出如此高级的图片编辑系统
26 0
|
1月前
|
Java Spring 容器
【Java】Spring如何扫描自定义的注解?
【Java】Spring如何扫描自定义的注解?
33 0
|
2月前
|
NoSQL Java 关系型数据库
凭借Java开发进阶面试秘籍(核心版)逆流而上
最近参加了面试或者身边有朋友在面试的兄弟有没有发现,现在的面试不仅会问八股文,还会考察框架、项目实战、算法数据结构等等,需要准备的越来越多。 其实面试的时候,并不是要求你所有的知识点都会,而是关键的问题答到点子上!这份《Java 开发进阶面试秘籍(核心版)》由 P8 面试官整体把控,目前已经更新了 30 万字! 资料中涵盖了一线大厂、中小厂面试真题,毕竟真题都是技术领域最经典的基础知识和经验沉淀的汇总,非常有必要学习掌握!双重 buff 叠加,offer 接到手软~ 点击此处取,这可能是你到目前为止领取的最具含金量的一份资料! 整套资料涵盖:Spring、Spring
|
1月前
|
Java 关系型数据库 MySQL
在Java的反射中,Class.forName和ClassLoader的区别
在Java的反射中,Class.forName和ClassLoader的区别
35 3
|
11天前
|
缓存 安全 Java
Java并发编程进阶:深入理解Java内存模型
【4月更文挑战第6天】Java内存模型(JMM)是多线程编程的关键,定义了线程间共享变量读写的规则,确保数据一致性和可见性。主要包括原子性、可见性和有序性三大特性。Happens-Before原则规定操作顺序,内存屏障和锁则保障这些原则的实施。理解JMM和相关机制对于编写线程安全、高性能的Java并发程序至关重要。
|
1月前
|
Java 编译器 程序员
Java中的异常处理:从基础到高级
【2月更文挑战第24天】本文将深入探讨Java中的异常处理,从基础的try-catch块到高级的异常处理策略。我们将了解如何使用Java的异常处理机制来提高代码的健壮性和可维护性,以及如何处理运行时和编译时的异常。
22 0
|
5天前
|
Java
Java配置大揭秘:读取自定义配置文件的绝佳指南
Java配置大揭秘:读取自定义配置文件的绝佳指南
11 0
Java配置大揭秘:读取自定义配置文件的绝佳指南
|
21天前
|
SQL 前端开发 Java
Java后端进阶之路: JavaWeb(四)
Java后端进阶之路: JavaWeb
33 1
|
XML SQL Java
Java后端进阶之路: JavaWeb(三)
Java后端进阶之路: JavaWeb
30 1
|
27天前
|
并行计算 安全 Java
深入理解Java并发编程:从基础到高级
【2月更文挑战第30天】 本文将深入探讨Java并发编程的核心概念和技术,包括线程、锁、同步、并发集合等。我们将从基础知识开始,逐步深入到高级主题,如Fork/Join框架、CompletableFuture和反应式编程。通过本文,你将能够理解并发编程的重要性,掌握Java中实现高效并发的关键技术和方法。