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

java實(shí)現(xiàn)插拔式加載用戶自定義插件

 更新時(shí)間:2025年09月16日 10:13:40   作者:Java八股文  
本文主要介紹了DatalinkX通過(guò)自定義URLClassLoader實(shí)現(xiàn)插件化加載外部數(shù)據(jù)源jar包,突破SPI機(jī)制依賴限制,使用戶無(wú)需修改源碼即可擴(kuò)展數(shù)據(jù)源同步功能,達(dá)成動(dòng)態(tài)插拔效果

前言

從23年底開(kāi)始維護(hù)自己的開(kāi)源項(xiàng)目,異構(gòu)數(shù)據(jù)源流轉(zhuǎn)系統(tǒng)datalinkx,系統(tǒng)支持不同數(shù)據(jù)源之間的數(shù)據(jù)同步,包括mysql、oracle、es、redis等等。

有一天一個(gè)同學(xué)問(wèn)我說(shuō)datalinkx系統(tǒng)支不支持用戶上傳自己的自定義數(shù)據(jù)源插件,不用動(dòng)datalinkx的源碼即可讓系統(tǒng)支持用戶自定義數(shù)據(jù)源的讀寫(xiě)同步呢。

我一聽(tīng)有點(diǎn)意思,一般我都是版本迭代后支持某個(gè)數(shù)據(jù)源的讀寫(xiě),能不能把這個(gè)能力開(kāi)放出去呢,這樣大家使用的時(shí)候就不需要等系統(tǒng)更新,上傳符合規(guī)范的插件包就可以。

也就是說(shuō)我們需要實(shí)現(xiàn),用戶只需要將其他數(shù)據(jù)源的同步j(luò)ar包,放到某個(gè)文件夾下,系統(tǒng)就會(huì)自動(dòng)掃描到這個(gè)jar包從而獲得對(duì)應(yīng)數(shù)據(jù)源的讀寫(xiě)能力。

SPI

通常聽(tīng)到插件化就會(huì)下意識(shí)的想起SPI,SPI是JDK內(nèi)置的一種類似服務(wù)提供發(fā)現(xiàn)的機(jī)制,比如java.sql.Driver接口,其他不同的數(shù)據(jù)源廠商可以針對(duì)這一接口做出不同的實(shí)現(xiàn), MySQL和PostgreSQL分別有不同的實(shí)現(xiàn)提供給用戶,利用SPI機(jī)制可以為某個(gè)接口尋找服務(wù)實(shí)現(xiàn)。

主要思想是將裝配的控制權(quán)移到程序之外,在模塊化設(shè)計(jì)中這個(gè)機(jī)制尤其重要,核心思想就解耦,具體實(shí)現(xiàn)可以參考jdbc的實(shí)現(xiàn)。

思考下利用SPI可以實(shí)現(xiàn)插拔式插件開(kāi)發(fā)嗎,似乎不可以,使用SPI必須在當(dāng)前classpath中,也就是說(shuō)雖然解耦了,但必須存在依賴,比如你想要讓系統(tǒng)支持PG,必須要在項(xiàng)目中引入PG驅(qū)動(dòng)依賴才可以加載到PG驅(qū)動(dòng)內(nèi)的相關(guān)類。

這樣還是要修改系統(tǒng)源代碼才能得到支持,這明顯是不符合我們的預(yù)期的。

自定義加載器

我們想要的效果是用戶可以開(kāi)發(fā)一個(gè)獨(dú)立的插件jar包,放到datalinkx的driver-dist目錄下,datalinkx即可獲得獨(dú)立插件jar包中的能力。

看到這里有準(zhǔn)備面試的jym心里默背一遍java類加載過(guò)程和雙親委派機(jī)制,背不下來(lái)的看完趕緊補(bǔ)上。我們知道一個(gè)JVM進(jìn)程正常情況下只能加載當(dāng)前classpath下的所有java類。

有沒(méi)有通過(guò)掃描固定路徑下的jar包,將外部java類加載當(dāng)當(dāng)前classpath的方式呢。有的兄弟,有的。

URLClassLoader

// 從driver-dist文件夾下讀取各個(gè)數(shù)據(jù)源插件
List<URL> dataSourcePlugins = JarLoaderUtil.loadJarsFromDirectory(DRIVER_DIST);
String targetJarName = String.format("datalinkx-driver-%s-1.0.0.jar", dsType.toLowerCase());
String targetClassName = getDriverClass(dsType);

URL targetJarUrl = dataSourcePlugins.stream()
        .filter(plugin -> plugin.getPath().endsWith(targetJarName))
        .findFirst()
        .orElseThrow(() -> new DatalinkXServerException(StatusCode.DRIVER_LOAD_FAIL, "系統(tǒng)未支持該數(shù)據(jù)源類型"));

// 使用自定義的 URLClassLoader 加載目標(biāo) JAR 包中的類
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{targetJarUrl}, Thread.currentThread().getContextClassLoader());
Class<?> clazz = Class.forName(targetClassName, true, urlClassLoader);

我們總結(jié)一下具體做了啥:

  1. 各個(gè)數(shù)據(jù)源模塊打包后都會(huì)自動(dòng)復(fù)制到datalinkx/driver-dist中
  2. 通過(guò)使用自定義 URLClassLoader加載器加載driver-dist文件夾內(nèi)的jar包
  3. 通過(guò)class.forName反射的方式生成對(duì)用對(duì)象

這樣我們就可以在當(dāng)前進(jìn)程中加載到外部jar包中的類,也就實(shí)現(xiàn)了Java插拔式加載用戶自定義插件功能。

到此這篇關(guān)于java實(shí)現(xiàn)插拔式加載用戶自定義插件的文章就介紹到這了,更多相關(guān)java 插拔式加載自定義插件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot生成和操作PDF的代碼詳解

    SpringBoot生成和操作PDF的代碼詳解

    本文主要介紹了在SpringBoot項(xiàng)目下,通過(guò)代碼和操作步驟,詳細(xì)的介紹了如何操作PDF,希望可以幫助到準(zhǔn)備通過(guò)JAVA操作PDF的你,項(xiàng)目框架用的SpringBoot,但在JAVA中代碼都是通用的,需要的朋友可以參考下
    2025-01-01
  • Java lambda list轉(zhuǎn)換map時(shí),把多個(gè)參數(shù)拼接作為key操作

    Java lambda list轉(zhuǎn)換map時(shí),把多個(gè)參數(shù)拼接作為key操作

    這篇文章主要介紹了Java lambda list轉(zhuǎn)換map時(shí),把多個(gè)參數(shù)拼接作為key操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • 如何理解SpringMVC

    如何理解SpringMVC

    Spring Web MVC是一種基于Java的實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將web層進(jìn)行職責(zé)解耦,基于請(qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型,框架的目的就是幫助我們簡(jiǎn)化開(kāi)發(fā)
    2021-06-06
  • java實(shí)現(xiàn)Redisson的基本使用

    java實(shí)現(xiàn)Redisson的基本使用

    Redisson是一個(gè)在Redis的基礎(chǔ)上實(shí)現(xiàn)的Java駐內(nèi)存數(shù)據(jù)網(wǎng)格客戶端,本文主要介紹了java實(shí)現(xiàn)Redisson的基本使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • springboot之配置雙kafka全過(guò)程

    springboot之配置雙kafka全過(guò)程

    這篇文章主要介紹了springboot之配置雙kafka全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • java實(shí)現(xiàn)Excel的導(dǎo)入導(dǎo)出

    java實(shí)現(xiàn)Excel的導(dǎo)入導(dǎo)出

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)Excel的導(dǎo)入導(dǎo)出,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • springboot+springmvc+mybatis項(xiàng)目整合

    springboot+springmvc+mybatis項(xiàng)目整合

    這篇文章主要為大家詳細(xì)介紹了springboot+springmvc+mybatis項(xiàng)目的整合,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Java聊天室之使用Socket實(shí)現(xiàn)傳遞對(duì)象

    Java聊天室之使用Socket實(shí)現(xiàn)傳遞對(duì)象

    這篇文章主要為大家詳細(xì)介紹了Java簡(jiǎn)易聊天室之使用Socket實(shí)現(xiàn)傳遞對(duì)象功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以了解一下
    2022-10-10
  • SpringBoot啟動(dòng)失敗Application?run?failed的問(wèn)題分析及解決辦法

    SpringBoot啟動(dòng)失敗Application?run?failed的問(wèn)題分析及解決辦法

    文章主要介紹了SpringBoot啟動(dòng)失敗的問(wèn)題分析和解決辦法,包括XML文件格式錯(cuò)誤、數(shù)據(jù)庫(kù)名稱錯(cuò)誤以及MyBatis掃描路徑問(wèn)題的排查和修復(fù)步驟,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • 分析ThreadLocal內(nèi)存泄漏問(wèn)題

    分析ThreadLocal內(nèi)存泄漏問(wèn)題

    ThreadLocal的作用是提供線程內(nèi)的局部變量,這種變量在線程生命周期內(nèi)起作用,減少同一個(gè)線程內(nèi)多個(gè)函數(shù)或者組件之間一些公共變量傳遞的復(fù)雜度,但是如果濫用ThreadLocal可能會(huì)導(dǎo)致內(nèi)存泄漏,所以本文將為大家分析ThreadLocal內(nèi)存泄漏問(wèn)題
    2023-07-07

最新評(píng)論

金坛市| 贵溪市| 汽车| 余江县| 固原市| 文昌市| 玛沁县| 平泉县| 宣汉县| 年辖:市辖区| 巴彦淖尔市| 阳原县| 南昌县| 东阿县| 新余市| 桃园市| 嘉鱼县| 牡丹江市| 宁晋县| 海原县| 介休市| 电白县| 渭源县| 康平县| 广安市| 乃东县| 黎川县| 平乐县| 鄂温| 和龙市| 北辰区| 蒙自县| 福安市| 新兴县| 麻阳| 贵港市| 乐清市| 平顶山市| 木兰县| 江达县| 银川市|