jvm进阶之自定义类加载器(代码片段)

编程小吉 编程小吉     2022-12-12     176

关键词:

自定义类加载器

1.作用

  • 隔离加载类

    在某些框架内进行中间件与应用的模块隔离,把类加载到不同的环境。

  • 修改类加载的方式

    类的加载模型并非强制的,应该根据实际情况在某个时间点按需进行动态加载。

  • 扩展加载源

    可以从数据库、网络、甚至是电视机机顶盒进行加载。

  • 防止源码泄露

    可以对Java源码进行编译时的加密,还原时的解密。

2.场景

  • 当实现类似进程内隔离效果时,类加载器可用作不同的命名空间,以提供类似容器、模块化的效果。
  • 当应用需要从不同的数据源获取类定义信息时,比如:网络数据源、操纵字节码来动态修改或者生成类。

3.注意

  • 在一般情况下,使用不同的类加载器去加载不同的功能模块,会提高应用程序的安全性。
  • 但如果涉及Java类型之间的相互转换,那么只有两个类型都是由同一个类加载器所加载的,才能进行类型转换,否则转换时会发生异常。

4.实现

  • 常见的有两种做法:重写loadClass方法、重写findClass方法。
  • 这两种方法本质上差不多,毕竟在loadClass方法中也会调用findClass方法。但是从逻辑上讲,我们最好不要直接修改loadClass方法里面的内部逻辑, 因为这个方法是实现双亲委派模型逻辑的地方,擅自修改这个方法会导致模型被破坏,容易造成问题,所以建议使用第二种做法。

代码示例

public class MyClassLoader extends ClassLoader 
    private String byteCodePath;

    public MyClassLoader(String byteCodePath) 
        this.byteCodePath = byteCodePath;
    

    public MyClassLoader(ClassLoader parent, String byteCodePath) 
        super(parent);
        this.byteCodePath = byteCodePath;
    

    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException 
        BufferedInputStream bis = null;
        ByteArrayOutputStream baos = null;
        
        try 
            // 获取字节码文件所在路径
            String fileName = byteCodePath + className + ".class";
            
            // 获取文件输入流
            bis = new BufferedInputStream(new FileInputStream(fileName));
            
            // 获取字节输出流
            baos = new ByteArrayOutputStream();
            
            // 将字节码文件写入到输出流当中
            int len;
            byte[] data = new byte[1024];
            while ((len = bis.read(data)) != -1) 
                baos.write(data, 0, len);
            
            
            // 将字节输出流转化为字节数组
            byte[] byteCodes = baos.toByteArray();
			
            // 调用defineClass方法完成类实例的创建
            Class clazz = defineClass(null, byteCodes, 0, byteCodes.length);
            
            return clazz;
         catch (IOException e) 
            e.printStackTrace();
         finally 
            try 
                if (baos != null) baos.close();
             catch (IOException e) 
                e.printStackTrace();
            
            try 
                if (bis != null) bis.close();
             catch (IOException e) 
                e.printStackTrace();
            
        

        return null;
    

public class MyClassLoaderTest 
    public static void main(String[] args) 
        MyClassLoader loader = new MyClassLoader("字节码文件所在根路径");

        try 
            Class clazz = loader.loadClass("Demo");
            
            System.out.println("加载此类的类加载器为:" + 
                               clazz.getClassLoader().getClass().getName());

            System.out.println("加载此类的类加载器的父加载器为:" + 
                               clazz.getClassLoader().getParent().getClass().getName());
         catch (ClassNotFoundException e) 
            e.printStackTrace();
        
    

jvm进阶之类加载器详解(代码片段)

类加载器详解一、类加载器概述1.作用2.分类3.重要性4.命名空间5.特性二、类加载器分类1.基本概述2.引导类加载器3.扩展类加载器4.系统类加载器5.自定义类加载器三、类加载器测试1.获取类加载器方式2.获取类加载器示例四、类加... 查看详情

jvm进阶之类加载器详解(代码片段)

类加载器详解一、类加载器概述1.作用2.分类3.重要性4.命名空间5.特性二、类加载器分类1.基本概述2.引导类加载器3.扩展类加载器4.系统类加载器5.自定义类加载器三、类加载器测试1.获取类加载器方式2.获取类加载器示例四、类加... 查看详情

jvm进阶之双亲委派机制(代码片段)

双亲委派机制1.概述2.本质3.实现4.优点5.弊端6.注意细节7.破坏示例8.热替换1.概述如果一个类加载器在接收到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父加载器去完成。依次递归ÿ... 查看详情

jvm进阶之双亲委派机制(代码片段)

双亲委派机制1.概述2.本质3.实现4.优点5.弊端6.注意细节7.破坏示例8.热替换1.概述如果一个类加载器在接收到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父加载器去完成。依次递归ÿ... 查看详情

tomcat源码篇自定义类加载器那点儿事儿(代码片段)

Tomcat进阶篇一、聊聊ClassLoader的那些事儿  我们要分析清楚Tomcat中的类加载器相关的内容之前我们还是需要把JVM中的类加载器给大家理清楚。1.类加载器的过程  类加载器的作用就是从文件系统或者网络中加载Class文件,... 查看详情

(转)jvm——自定义类加载器(代码片段)

背景:为什么要自定义,如何自定义,实现过程转载:http://blog.csdn.net/SEU_Calvin/article/details/523151250. 为什么需要自定义类加载器  网上的大部分自定义类加载器文章,几乎都是贴一段实现代码,然后分析一两句自定义Cl... 查看详情

jvm:如何实现一个自定义类加载器?(代码片段)

JVM:如何实现一个自定义类加载器?1.为什么要自定义加载器2.如何实现自定义加载器3.能不能自己写一个java.lang.String1.为什么要自定义加载器原因:1、存放在自定义路径上的类,需要通过自定义类加载器去加载。【注... 查看详情

jvm的艺术—类加载器篇(代码片段)

...内容,没看过的小伙伴请加关注。今天我们继续。什么是定义类加载器和初始化类加载器?定义类加载器:假设我们的某一个类是由ExtClassLoader加载的,那么ExtClassLoader称为该类的定义类加载器初始化加载器:能够返回Class对象引... 查看详情

jvm进阶之双亲委派机制(代码片段)

双亲委派机制1.概述2.本质3.实现4.优点5.弊端6.注意细节7.破坏示例8.热替换1.概述如果一个类加载器在接收到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父加载器去完成。依次递归ÿ... 查看详情

jvm类加载器篇(下)(代码片段)

JVM类加载器篇1.虚拟机自带的类加载器2.用户自定义的类加载器3.类加载器的常见方法4.类加载器的双亲委派机制5.类加载器的引用1.虚拟机自带的类加载器启动类加载器(也叫作引导类加载器,BootStrapClassLoader)这个类... 查看详情

jvm自定义类加载器(代码片段)

 编写原则在JDK1.2之前,在自定义类加载器时,总会去重写loadClass方法,从而实现自定义的类加载类,但是JDK1.2之后已不再建议用户去覆盖loadClass方法,而是建议把自定义的类加载逻辑写在findClass方法中在编写自定义类加载器... 查看详情

jvm进阶之类加载过程详解(下篇)(代码片段)

类加载过程详解下篇一、类的初始化阶段1.初始化方法2.初始化过程3.类初始化方法的安全性4.类初始化的使用二、类的使用阶段三、类的卸载阶段1.类、类加载器、类的实例之间的关系2.类的生命周期3.类的卸载一、类的初始化阶... 查看详情

jvm进阶之类加载过程详解(下篇)(代码片段)

类加载过程详解下篇一、类的初始化阶段1.初始化方法2.初始化过程3.类初始化方法的安全性4.类初始化的使用二、类的使用阶段三、类的卸载阶段1.类、类加载器、类的实例之间的关系2.类的生命周期3.类的卸载一、类的初始化阶... 查看详情

jvm虚拟机详解类加载器的分类(代码片段)

...器。分别为引导类加载器(BootstrapClassLoader)和自定义类加载器(User-DefinedClassLoader)从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范却没有这么定... 查看详情

从源码透彻理解jvm类加载机制(代码片段)

...xff0c;分别为引导类加载器(BootstrapClassLoader)和自定义类加载器(User-Def 查看详情

jvm入门(代码片段)

...叫系统类加载器,加载当前应用的classpath的所有类用户自定义加载器Java.lang.ClassLoader的子类,用户可以定制类的加载方式  类装载器ClassLoader3Code案例sun.misc.Launcher它是一个java虚拟机的入口应用某个特定的类加载器在接到... 查看详情

jvm第六卷---类加载机制(代码片段)

...加载器扩展类加载器双亲委派模式线程上下文类加载器自定义类加载器破坏双亲委派模型的几种做法类加载机制Java虚拟机把描述类结构的数据从Class文件中加载到内存,并对数据进行校验,转换解析和初始化,最终形... 查看详情

jvm进阶之类加载过程详解(上篇)(代码片段)

类加载过程详解上篇一、类的生命周期二、类的加载阶段三、类的链接阶段1.进行验证(Verification)2.进行准备(Preparation)3.进行解析(Resolution)一、类的生命周期在Java中数据类型分为基本数据类型和引用数据类型,其中基本数据类... 查看详情