欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java自定義類加載器如何實現(xiàn)類隔離

 更新時間:2022年11月19日 11:27:54   作者:快樂崇拜234  
這篇文章主要介紹了java自定義類加載器如何實現(xiàn)類隔離問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

網(wǎng)上java自定義類加載器很多容易找到,但是都是加載的單個類,如果被加載的類,有引用了其他類怎么辦呢?接下來看一下如何來處理這種情況

有時候一個項目中可能會引用不同版本的第三方依賴,比如筆者在升級hbase系統(tǒng)時,代理層就同時用到了1.X和2.X版本的hbase-client的jar包。

當時是使用的阿里的SOFAArk來實現(xiàn)的。

它的本質(zhì)就是是喲個類加載來實現(xiàn)的,接下來就通過一個小例子來通過自定義類加載器實現(xiàn)類隔離。

下面實例實現(xiàn)了在同一個應(yīng)用里加載了兩個類名報名完全相同的Hello 和Dog類:

自定義類加載器

準備

準備工作,在D盤的a,b兩個目錄下準備Hello.class 和 Dog.class 兩個文件,可以使用javac編譯。

//a文件夾:
public class Hello {
    private String name;

    public Hello(String name) {
        this.name = name;
    }

    public void sayHello() {
		Dog d =new Dog();
		d.hi();
        System.out.println("a hello " + name + "  "+ this.getClass().getClassLoader());
    }
}

public class Dog {

    public void hi() {
        System.out.println("a hi ...  "+ this.getClass().getClassLoader());
    }
}


//b文件夾
public class Hello {
    private String name;

    public Hello(String name) {
        this.name = name;
    }

    public void sayHello() {
		Dog d =new Dog();
		d.hi();
        System.out.println("b hello " + name + "  "+ this.getClass().getClassLoader());
    }
}

public class Dog {

    public void hi() {
        System.out.println("b hi ...  "+ this.getClass().getClassLoader());
    }
}

通過URLClassLoader來實現(xiàn)【推薦】

類加載器會主動加載被引用的類。比如類A依賴引用了類B ,則只需要主動加載類A即可,類B會自動加載,而且加載類B的類加載器與類A相同。

/**
 * URLClassLoader
 * 推薦此方法
 */
@Test
public void test0() {
    try {
        System.out.println( this.getClass().getClassLoader());

        URLClassLoader diskLoader = new URLClassLoader(new URL[]{new URL("file:/D:/liubenlong/a/")});//最后面的斜杠需要添加
        URLClassLoader diskLoader1 = new URLClassLoader(new URL[]{new URL("file:/D:/liubenlong/b/")});

        //加載class文件
        Class clz = diskLoader.loadClass("Hello");
        Constructor constructor = clz.getConstructor(String.class);
        Object obj = constructor.newInstance("tom");

        /**
         * 類Hello引用了類Dog,類加載器會主動加載被引用的類。
         * 注意一般是我們使用 URLClassLoader 實現(xiàn)自定義的類加載器。如果使用classLoader,則需要重寫findClass方法來實現(xiàn)類字節(jié)碼的加載
         */
        Method method = clz.getMethod("sayHello", null);
        //通過反射調(diào)用Test類的say方法
        method.invoke(obj, null);


        Class clz1 = diskLoader1.loadClass("Hello");
        Constructor constructor1 = clz1.getConstructor(String.class);
        Object obj1 = constructor1.newInstance("cat");

        Method method1 = clz1.getMethod("sayHello", null);
        //通過反射調(diào)用Test類的say方法
        method1.invoke(obj1, null);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

輸出

jdk.internal.loader.ClassLoaders$AppClassLoader@1f89ab83
a hi ...  java.net.URLClassLoader@3891771e
a hello tom  java.net.URLClassLoader@3891771e
b hi ...  java.net.URLClassLoader@78ac1102
b hello cat  java.net.URLClassLoader@78ac1102

通過繼承ClassLoader實現(xiàn)

網(wǎng)上說可以自定義類加載器實現(xiàn),接下來我們看一下(jdk11直接忽略,因為編譯不通過,下面是在jdk8版本測試)。

package 自定義類加載器;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;

/**
 * 自定義ClassLoader
 */
public class MyClassLoader extends ClassLoader {
    protected Class<?> findClass(String path, String name) {
        try {
            FileInputStream in = new FileInputStream(path + name + ".class");
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int len = -1;
            while ((len = in.read(buf)) != -1) {
                baos.write(buf, 0, len);
            }
            in.close();
            byte[] classBytes = baos.toByteArray();
            return defineClass(name, classBytes, 0, classBytes.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

編寫測試類

package 自定義類加載器;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ClassLoaderTest {

    /**
     * 集成ClassLoader,重寫findClass實現(xiàn)自定義類加載器
     */
    @Test
    public void test1() {
        try {
            MyClassLoader diskLoader = new MyClassLoader();
            MyClassLoader diskLoader1 = new MyClassLoader();

            //依賴的類需要提前加載,不是應(yīng)該自動加載的嗎?
            diskLoader.findClass("D:\\liubenlong\\a\\", "Dog");
            diskLoader1.findClass("D:\\liubenlong\\b\\", "Dog");

            //加載class文件
            Class clz = diskLoader.findClass("D:\\liubenlong\\a\\", "Hello");
            Constructor constructor = clz.getConstructor(String.class);
            Object obj = constructor.newInstance("tom");

            Method method = clz.getMethod("sayHello", null);
            //通過反射調(diào)用Test類的say方法
            method.invoke(obj, null);


            Class clz1 = diskLoader1.findClass("D:\\liubenlong\\b\\", "Hello");
            Constructor constructor1 = clz1.getConstructor(String.class);
            Object obj1 = constructor1.newInstance("cat");

            Method method1 = clz1.getMethod("sayHello", null);
            //通過反射調(diào)用Test類的say方法
            method1.invoke(obj1, null);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

運行結(jié)果:

a hi ...
a hello tom
b hi ...
b hello cat

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 自定義Jackson的ObjectMapper如何實現(xiàn)@ResponseBody的自定義渲染

    自定義Jackson的ObjectMapper如何實現(xiàn)@ResponseBody的自定義渲染

    這篇文章主要介紹了自定義Jackson的ObjectMapper如何實現(xiàn)@ResponseBody的自定義渲染,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java排序算法中的插入排序算法實現(xiàn)

    Java排序算法中的插入排序算法實現(xiàn)

    這篇文章主要介紹了Java排序算法中的插入排序算法實現(xiàn),插入排序是將數(shù)組中的數(shù)據(jù)分為兩個區(qū)間,已排序區(qū)間和未排序區(qū)間,其中已排序區(qū)間初始只有一個元素,就是數(shù)組的第一個元素,需要的朋友可以參考下
    2023-12-12
  • java-制表符\t的使用說明

    java-制表符\t的使用說明

    這篇文章主要介紹了java-制表符\t的使用說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Jdk1.8 HashMap實現(xiàn)原理詳細介紹

    Jdk1.8 HashMap實現(xiàn)原理詳細介紹

    這篇文章主要介紹了Jdk1.8 HashMap實現(xiàn)原理詳細介紹的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • Spring深入分析容器接口作用

    Spring深入分析容器接口作用

    Spring內(nèi)部提供了很多表示Spring容器的接口和對象,我們今天來看看幾個比較常見的容器接口和具體的實現(xiàn)類,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • shardingJdbc3.x?版本的分頁bug問題解析

    shardingJdbc3.x?版本的分頁bug問題解析

    這篇文章主要為大家介紹了shardingJdbc3.x?版本的分頁問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • SpringBoot項目如何把接口參數(shù)中的空白值替換為null值(推薦)

    SpringBoot項目如何把接口參數(shù)中的空白值替換為null值(推薦)

    這篇文章主要介紹了SpringBoot項目如何把接口參數(shù)中的空白值替換為null值(推薦),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • java獲取本月日歷表的方法

    java獲取本月日歷表的方法

    這篇文章主要為大家詳細介紹了java獲取本月日歷表的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • springboot 傳參校驗@Valid及對其的異常捕獲方式

    springboot 傳參校驗@Valid及對其的異常捕獲方式

    這篇文章主要介紹了springboot 傳參校驗@Valid及對其的異常捕獲方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • 在SpringBoot中使用jwt實現(xiàn)token身份認證的實例代碼

    在SpringBoot中使用jwt實現(xiàn)token身份認證的實例代碼

    你還不會在SpringBoot中使用jwt實現(xiàn)token身份認證嗎,本文小編就給大家詳細的介紹一下在SpringBoot中使用jwt實現(xiàn)token身份認證的實例代碼,感興趣的同學可以自己動手試一試
    2023-09-09

最新評論