最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java自定義類加載器實現(xiàn)類隔離詳解

 更新時間:2023年03月02日 09:05:59   作者:kamier  
由于每種組件的不同版本所依賴的jar包不同,我們可以借鑒tomcat的實現(xiàn)方式,通過自定義類加載器打破雙親委派機制來實現(xiàn)類隔離,從而達(dá)到操作多組件多版本的目的。本文就來和大家詳細(xì)聊聊實現(xiàn)方法

一、背景

某服務(wù)需要連接操作多種組件(每種組件可能有多個版本),如kafka、mongodb、es、mysql等等,并且后續(xù)需要適配更多的組件。

主要難點:連接操作多組件多版本,且同種組件的不同版本所依賴的jar包可能不一樣,操作源碼也可能發(fā)生改變,項目無法直接依賴jar包,會產(chǎn)生類沖突

二、解決思路

由于每種組件的不同版本所依賴的jar包不同,我們可以借鑒tomcat的實現(xiàn)方式,通過自定義類加載器打破雙親委派機制來實現(xiàn)類隔離,從而達(dá)到操作多組件多版本的目的。

2.1 創(chuàng)建依賴所在目錄

針對每一種組件我們創(chuàng)建一個目錄,比如/data/kafka、/data/mongodb、/data/es等,且每種組件的不同版本創(chuàng)建對應(yīng)的子目錄,比如/data/kafka/0.10、/data/kafka/0.11,目錄結(jié)構(gòu)如下

| ----/data
| --------/kafka
| ------------/0.10
| ------------/0.11
| --------/mysql
| ------------/5.7
| ------------/8.0
| ...

把每種組件不同版本對應(yīng)的依賴包放在各個子目錄下面。

2.2 定義操作接口

在common公共模塊中定義一個接口AbstractOperator,該接口定義一些通用方法,如下:

public interface Operator {
    /**
     * 測試連接
     * @param connectionInfo
     * @return
     */
    boolean testConnection(String connectionInfo);

    /**
     * 獲取組件版本
     * @return
     */
    String getVersion(String connectionInfo);
}

再定義各種組件的接口,如KafkaOperator、MysqlOperator等,使其繼承該通用接口。組件接口內(nèi)部包含一些組件自身的操作,如KafkaOperator中定義了getTopics、createTopic、deleteTopic等方法。代碼如下:

public interface KafkaOperator extends Operator{
    /**
     * 獲取topic列表
     * @param connectionInfo
     * @return
     */
    List<String> getTopics(String connectionInfo);

    /**
     * 創(chuàng)建topic
     * @param connectionInfo
     * @param topic
     * @return
     */
    boolean createTopic(String connectionInfo, String topic);

    /**
     * 刪除topic
     * @param connectionInfo
     * @param topic
     * @return
     */
    boolean deleteTopic(String connectionInfo, String topic);
}

2.3 編寫并構(gòu)建業(yè)務(wù)包

大致步驟如下:

1.針對每種組件的不同版本,可以在項目下新建一個模塊,該模塊依賴common公共模塊

2.創(chuàng)建入口類com.kamier.Entry(所有組件的不同版本的入口類的全限定名統(tǒng)一為com.kamier.Entry),并實現(xiàn)對應(yīng)的組件接口,比如Kafka的0.10版本,那么就實現(xiàn)KafkaOperator接口。

3.編寫業(yè)務(wù)邏輯代碼

public class Entry implements KafkaOperator {
    @Override
    public List<String> getTopics(String connectionInfo) {
        return null;
    }

    @Override
    public boolean createTopic(String connectionInfo, String topic) {
        return false;
    }

    @Override
    public boolean deleteTopic(String connectionInfo, String topic) {
        return false;
    }

    @Override
    public boolean testConnection(String connectionInfo) {
        return false;
    }

    @Override
    public String getVersion(String connectionInfo) {
        return null;
    }
}

4.打成jar包

5.將jar包放在對應(yīng)的目錄下,與依賴包同級,如/data/kafka/0.10

2.4 自定義類加載器

經(jīng)過前面的準(zhǔn)備工作,組件的每個版本的目錄下都有了相應(yīng)的依賴包和業(yè)務(wù)包。

開始編寫一個自定義類加載器繼承URLClassLoader,重寫loadClass方法,優(yōu)先加載當(dāng)前類加載器路徑下的class來打破雙親委派模式,代碼如下

public static class MyClassLoader extends URLClassLoader {

        public MyClassLoader(URL[] urls) {
            super(urls);
        }

        public Class<?> loadClass(String name) throws ClassNotFoundException {
            synchronized (getClassLoadingLock(name)) {
                // 先檢查當(dāng)前類加載器是否已經(jīng)裝載該類
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    try {
                        // 在當(dāng)前類加載器的路徑下查找
                        c = findClass(name);
                    } catch (ClassNotFoundException e) {
                        // 說明在當(dāng)前類加載器的路徑下沒有找到
                    }

                    if (c == null) {
                        // 走雙親委派機制
                        if (getParent() != null) {
                            c = getParent().loadClass(name);
                        }
                    }
                }
                return c;
            }
        }
    }

針對每種組件的不同版本,我們創(chuàng)建與其對應(yīng)的自定義類加載器,并將該版本對應(yīng)目錄下的所有jar包(包括依賴包和業(yè)務(wù)包)的URL傳入。

2.5 主流程步驟

步驟如下:

當(dāng)我們從頁面上接收到一個獲取Kafka(版本為0.10)topic列表的請求時,先判斷是否已經(jīng)初始化過Kafka(0.10版本)的類加載器,如果還未初始化,則進行類加載器的初始化。

URL[] urls = null;
File dir = new File("/data/kafka/0.10");
if (dir.isDirectory()) {
    File[] files = dir.listFiles();
    urls = new URL[files.length];
    for (int i = 0; i < files.length; i++) {
        urls[i] = files[i].toURL();
    }
}

MyClassLoader contextClassLoader = new MyClassLoader(urls);

通過類加載器加載入口類com.kamier.Entry并實例化,通過反射調(diào)用對應(yīng)的方法(組件與其對應(yīng)的方法列表可以統(tǒng)一維護在數(shù)據(jù)庫中)。

Class loadClass = contextClassLoader.loadClass("com.kamier.Entry");
Object entry = loadClass.newInstance();
Method method = loadClass.getDeclaredMethod("getTopics");
List<String> a = (List) method.invoke(entry, 參數(shù));

獲取到結(jié)果并返回

三、總結(jié)

至此整個實現(xiàn)步驟就結(jié)束了,我們通過自定義類加載器的方式來實現(xiàn)類隔離,從而達(dá)到操作多組件多版本的目的。

到此這篇關(guān)于Java自定義類加載器實現(xiàn)類隔離詳解的文章就介紹到這了,更多相關(guān)Java類加載器實現(xiàn)類隔離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用filebeat收集并解析springboot日志過程示例

    使用filebeat收集并解析springboot日志過程示例

    這篇文章主要為大家介紹了使用filebeat收集并解析springboot日志實現(xiàn)過程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • 詳解Struts2標(biāo)簽遍歷

    詳解Struts2標(biāo)簽遍歷

    這篇文章主要介紹了Struts2標(biāo)簽遍歷,以及相關(guān)的用法示例,需要的朋友可以參考下。
    2017-09-09
  • 詳解idea中web.xml默認(rèn)版本問題解決

    詳解idea中web.xml默認(rèn)版本問題解決

    這篇文章主要介紹了詳解idea中web.xml默認(rèn)版本問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • java編程無向圖結(jié)構(gòu)的存儲及DFS操作代碼詳解

    java編程無向圖結(jié)構(gòu)的存儲及DFS操作代碼詳解

    這篇文章主要介紹了java編程無向圖結(jié)構(gòu)的存儲及DFS操作代碼詳解,具有一定借鑒價值,需要的朋友可以了解下。
    2017-12-12
  • Java 交換兩個變量的數(shù)值實現(xiàn)方法

    Java 交換兩個變量的數(shù)值實現(xiàn)方法

    下面小編就為大家?guī)硪黄狫ava 交換兩個變量的數(shù)值實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • Spring Cloud Gateway內(nèi)置的斷言和過濾器作用說明

    Spring Cloud Gateway內(nèi)置的斷言和過濾器作用說明

    這篇文章主要介紹了Spring Cloud Gateway內(nèi)置的斷言和過濾器作用說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java設(shè)計模式之java訪問者模式詳解

    Java設(shè)計模式之java訪問者模式詳解

    這篇文章主要介紹了JAVA設(shè)計模式之訪問者模式,簡單說明了訪問者模式的原理,并結(jié)合實例分析了java訪問者模式的定義與用法,需要的朋友可以參考下
    2021-09-09
  • Java局部內(nèi)部類原理與用法實例分析

    Java局部內(nèi)部類原理與用法實例分析

    這篇文章主要介紹了Java局部內(nèi)部類原理與用法,結(jié)合實例形式分析了Java局部內(nèi)部類功能、用法及相關(guān)操作注意事項,需要的朋友可以參考下
    2019-09-09
  • Spring?MVC內(nèi)置過濾器功能示例詳解

    Spring?MVC內(nèi)置過濾器功能示例詳解

    這篇文章主要為大家介紹了Spring?MVC內(nèi)置過濾器使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • 聊聊Spring Cloud Cli 初體驗

    聊聊Spring Cloud Cli 初體驗

    這篇文章主要介紹了聊聊Spring Cloud Cli 初體驗,SpringBoot CLI 是spring Boot項目的腳手架工具。非常具有實用價值,需要的朋友可以參考下
    2018-04-04

最新評論

大邑县| 新龙县| 南康市| 辽源市| 深泽县| 磴口县| 滦平县| 曲周县| 鸡泽县| 兰州市| 得荣县| 凭祥市| 大荔县| 遵义县| 二连浩特市| 鄢陵县| 昭通市| 沙洋县| 银川市| 桃园县| 进贤县| 勐海县| 根河市| 神池县| 金塔县| 丰镇市| 长葛市| 旺苍县| 集安市| 凉城县| 平利县| 新安县| 利津县| 遵义市| 柯坪县| 南川市| 大连市| 广丰县| 乌兰县| 海宁市| 深泽县|