chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

系統(tǒng)完成熱部署,并切換該接口的實現

Android編程精選 ? 來源:zhangzhiqiang_0912 ? 作者:Android編程精選 ? 2022-07-23 11:03 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

近期開發(fā)系統(tǒng)過程中遇到的一個需求,系統(tǒng)給定一個接口,用戶可以自定義開發(fā)該接口的實現,并將實現打成jar包,上傳到系統(tǒng)中。系統(tǒng)完成熱部署,并切換該接口的實現。

定義簡單的接口

這里以一個簡單的計算器功能為例,接口定義比較簡單,直接上代碼。

publicinterfaceCalculator{
intcalculate(inta,intb);
intadd(inta,intb);
}

該接口的一個簡單的實現

考慮到用戶實現接口的兩種方式,使用spring上下文管理的方式,或者不依賴spring管理的方式,這里稱它們?yōu)樽⒔夥绞胶头瓷浞绞健?/span>calculate方法對應注解方式,add方法對應反射方式。計算器接口實現類的代碼如下:

@Service
publicclassCalculatorImplimplementsCalculator{
@Autowired
CalculatorCorecalculatorCore;
/**
*注解方式
*/
@Override
publicintcalculate(inta,intb){
intc=calculatorCore.add(a,b);
returnc;
}
/**
*反射方式
*/
@Override
publicintadd(inta,intb){
returnnewCalculatorCore().add(a,b);
}
}

這里注入CalculatorCore的目的是為了驗證在注解模式下,系統(tǒng)可以完整的構造出bean的依賴體系,并注冊到當前spring容器中。CalculatorCore的代碼如下:

@Service
publicclassCalculatorCore{
publicintadd(inta,intb){
returna+b;
}
}

反射方式熱部署

用戶把jar包上傳到系統(tǒng)的指定目錄下,這里定義上傳jar文件路徑為jarAddress,jar的Url路徑為jarPath。

privatestaticStringjarAddress="E:/zzq/IDEA_WS/CalculatorTest/lib/Calculator.jar";
privatestaticStringjarPath="file:/"+jarAddress;

并且可以要求用戶填寫jar包中接口實現類的完整類名。接下來系統(tǒng)要把上傳的jar包加載到當前線程的類加載器中,然后通過完整類名,加載得到該實現的Class對象。然后反射調用即可,完整代碼:

/**
*熱加載Calculator接口的實現反射方式
*/
publicstaticvoidhotDeployWithReflect()throwsException{
URLClassLoaderurlClassLoader=newURLClassLoader(newURL[]{newURL(jarPath)},Thread.currentThread().getContextClassLoader());
Classclazz=urlClassLoader.loadClass("com.nci.cetc15.calculator.impl.CalculatorImpl");
Calculatorcalculator=(Calculator)clazz.newInstance();
intresult=calculator.add(1,2);
System.out.println(result);
}

注解方式熱部署

如果用戶上傳的jar包含了spring的上下文,那么就需要掃描jar包里的所有需要注入spring容器的bean,注冊到當前系統(tǒng)的spring容器中。其實,這就是一個類的熱加載+動態(tài)注冊的過程。

直接上代碼:

/**
*加入jar包后動態(tài)注冊bean到spring容器,包括bean的依賴
*/
publicstaticvoidhotDeployWithSpring()throwsException{
SetclassNameSet=DeployUtils.readJarFile(jarAddress);
URLClassLoaderurlClassLoader=newURLClassLoader(newURL[]{newURL(jarPath)},Thread.currentThread().getContextClassLoader());
for(StringclassName:classNameSet){
Classclazz=urlClassLoader.loadClass(className);
if(DeployUtils.isSpringBeanClass(clazz)){
BeanDefinitionBuilderbeanDefinitionBuilder=BeanDefinitionBuilder.genericBeanDefinition(clazz);
defaultListableBeanFactory.registerBeanDefinition(DeployUtils.transformName(className),beanDefinitionBuilder.getBeanDefinition());
}
}
}

在這個過程中,將jar加載到當前線程類加載器的過程和之前反射方式是一樣的。然后掃描jar包下所有的類文件,獲取到完整類名,并使用當前線程類加載器加載出該類名對應的class對象。判斷該class對象是否帶有spring的注解,如果包含,則將該對象注冊到系統(tǒng)的spring容器中。

DeployUtils包含讀取jar包所有類文件的方法、判斷class對象是否包含sping注解的方法、獲取注冊對象對象名的方法。代碼如下:

/**
*讀取jar包中所有類文件
*/
publicstaticSetreadJarFile(StringjarAddress)throwsIOException{
SetclassNameSet=newHashSet<>();
JarFilejarFile=newJarFile(jarAddress);
Enumerationentries=jarFile.entries();//遍歷整個jar文件
while(entries.hasMoreElements()){
JarEntryjarEntry=entries.nextElement();
Stringname=jarEntry.getName();
if(name.endsWith(".class")){
StringclassName=name.replace(".class","").replaceAll("/",".");
classNameSet.add(className);
}
}
returnclassNameSet;
}
/**
*方法描述判斷class對象是否帶有spring的注解
*/
publicstaticbooleanisSpringBeanClass(Classcla){
if(cla==null){
returnfalse;
}
//是否是接口
if(cla.isInterface()){
returnfalse;
}
//是否是抽象類
if(Modifier.isAbstract(cla.getModifiers())){
returnfalse;
}
if(cla.getAnnotation(Component.class)!=null){
returntrue;
}
if(cla.getAnnotation(Repository.class)!=null){
returntrue;
}
if(cla.getAnnotation(Service.class)!=null){
returntrue;
}
returnfalse;
}
/**
*類名首字母小寫作為spring容器beanMap的key
*/
publicstaticStringtransformName(StringclassName){
Stringtmpstr=className.substring(className.lastIndexOf(".")+1);
returntmpstr.substring(0,1).toLowerCase()+tmpstr.substring(1);
}

刪除jar時,需要同時刪除spring容器中注冊的bean

在jar包切換或刪除時,需要將之前注冊到spring容器的bean刪除。spring容器的bean的刪除操作和注冊操作是相逆的過程,這里要注意使用同一個spring上下文。

代碼如下:

/**
*刪除jar包時需要在spring容器刪除注入
*/
publicstaticvoiddelete()throwsException{
SetclassNameSet=DeployUtils.readJarFile(jarAddress);
URLClassLoaderurlClassLoader=newURLClassLoader(newURL[]{newURL(jarPath)},Thread.currentThread().getContextClassLoader());
for(StringclassName:classNameSet){
Classclazz=urlClassLoader.loadClass(className);
if(DeployUtils.isSpringBeanClass(clazz)){
defaultListableBeanFactory.removeBeanDefinition(DeployUtils.transformName(className));
}
}
}

測試

測試類手動模擬用戶上傳jar的功能。測試函數寫了個死循環(huán),一開始沒有找到jar會拋出異常,捕獲該異常并睡眠10秒。這時候可以把jar手動放到指定的目錄下。

代碼如下:

ApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext.xml");
DefaultListableBeanFactorydefaultListableBeanFactory=(DefaultListableBeanFactory)applicationContext.getAutowireCapableBeanFactory();
while(true){
try{
hotDeployWithReflect();
//hotDeployWithSpring();
//delete();
}catch(Exceptione){
e.printStackTrace();
Thread.sleep(1000*10);
}
}

-End-

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    9507

    瀏覽量

    156890
  • 代碼
    +關注

    關注

    30

    文章

    4965

    瀏覽量

    73851

原文標題:動態(tài)上傳jar包熱部署實戰(zhàn)

文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    CoolMonitor 監(jiān)控系統(tǒng)部署及公網訪問方案

    現代的界面設計。 功能特點 多種監(jiān)控類型:支持HTTP/HTTPS網站、API接口、HTTPS證書過期、TCP端口、MySQL/Redis數據庫等多種監(jiān)控 推送監(jiān)控:支持被動接收客戶端的心跳推送,實現不可直接訪問設備的監(jiān)控 精美界面:深色/淺色主題
    的頭像 發(fā)表于 01-19 14:42 ?833次閱讀
    CoolMonitor 監(jiān)控<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>部署</b>及公網訪問方案

    本地部署微信公眾號文章搜索MCP服務實現遠程訪問

    本文介紹如何在本地部署基于FastAPI的微信公眾號文章搜索MCP服務,通過內網穿透實現公網訪問,支持關鍵詞搜索。
    的頭像 發(fā)表于 01-12 14:58 ?848次閱讀
    本地<b class='flag-5'>部署</b>微信公眾號文章搜索MCP服務<b class='flag-5'>并</b><b class='flag-5'>實現</b>遠程訪問

    尼日利亞MTN攜手華為完成RuralCow全球首商用部署

    近日,尼日利亞MTN攜手華為完成普惠聯(lián)接RuralCow解決方案商用部署方案實現了“一盒子一站點”的極簡創(chuàng)新突破,可助力偏遠農村地區(qū)低成本、高效率地
    的頭像 發(fā)表于 12-08 13:41 ?834次閱讀

    電能質量在線監(jiān)測裝置自診斷功能的硬件層實時監(jiān)測的冗余切換是如何實現的?

    硬件層冗余切換的核心是 通過專用切換電路 + 硬件觸發(fā)信號 + 同步機制 ,實現主備模塊(如電源、ADC、通信)的毫秒級無縫切換,全程不依賴復雜軟件,僅通過硬件邏輯
    的頭像 發(fā)表于 11-06 10:54 ?833次閱讀

    如何利用XPIO構建實現帶有Strobe的高速接口設計

    在 AMD Versal 自適應 SoC 器件中,SelectIO 是實現高速接口的重要組成部分。它為器件提供了靈活且高性能的通用 I/O 資源,支持多種工作模式,能夠滿足源同步接口、異步接口
    的頭像 發(fā)表于 10-17 09:22 ?2433次閱讀
    如何利用XPIO構建<b class='flag-5'>并</b><b class='flag-5'>實現</b>帶有Strobe的高速<b class='flag-5'>接口</b>設計

    功率器件設計基礎(十四)----成像儀測溫度概述

    摘要功率半導體熱設計是實現IGBT、SiC高功率密度設計的基礎,只有掌握功率半導體的設計基礎知識和測試的基本技能,才能完成精確設計,提高功率器件的利用率,降低
    的頭像 發(fā)表于 09-12 17:05 ?878次閱讀
    功率器件<b class='flag-5'>熱</b>設計基礎(十四)----<b class='flag-5'>熱</b>成像儀測溫度概述

    HT 流暢過渡動畫 × 場景切換實現方案

    在圖撲 HT 項目中,尤其是復雜應用里,單一場景或圖紙通常難以承載所有需求,因此在多個圖紙或場景之間進行切換是一種常見的實現方式。本文將深入解析圖撲 HT 項目中場景/圖紙切換的核心實現
    的頭像 發(fā)表于 09-03 14:49 ?834次閱讀
    HT 流暢過渡動畫 × 場景<b class='flag-5'>切換</b><b class='flag-5'>實現</b>方案

    曙光存儲支持西湖大學高性能計算中心部署完成全新存儲系統(tǒng)

    近日,曙光存儲支持西湖大學高性能計算中心部署完成全新存儲系統(tǒng),為AI研發(fā)、科學計算和信息化平臺等提供存力支持。性能實測顯示,該系統(tǒng)單節(jié)點帶寬可達150GB/s,是國際友商的近4倍,充分
    的頭像 發(fā)表于 08-25 11:48 ?1213次閱讀

    深度解析:雙卡切換的SIM卡電路設計原則與實現!

    實現穩(wěn)定的雙卡切換功能,電路設計必須遵循嚴格的技術規(guī)范。本文系統(tǒng)梳理SIM卡接口的電氣特性、時序要求及ESD防護策略,揭秘雙卡切換背后的電
    的頭像 發(fā)表于 07-17 16:14 ?915次閱讀
    深度解析:雙卡<b class='flag-5'>切換</b>的SIM卡電路設計原則與<b class='flag-5'>實現</b>!

    Context接口切換介紹

    ; isUpdatingConfigurations():Promise;Stage模型無對應接口系統(tǒng)環(huán)境變化時,應用不會重啟,調用onConfigurationUpdated接口通知應用,
    發(fā)表于 06-06 06:12

    HarmonyOS5云服務技術分享--Serverless抽獎模板部署

    名\"} 3?? ??部署執(zhí)行?? 確認參數無誤后點擊\"開始部署\" 若失敗可嘗試清緩存重新部署 建議部署時截圖保存配置參數 4?? ??云函數關聯(lián)??
    發(fā)表于 05-22 20:25

    無人職守自動安裝部署操作系統(tǒng)指南

    當組織有服務器需要部署linux系統(tǒng)時,需要通過網絡方式安裝結合自動應答文件,實現無人職守自動安裝部署操作
    的頭像 發(fā)表于 05-22 13:38 ?942次閱讀
    無人職守自動安裝<b class='flag-5'>部署</b>操作<b class='flag-5'>系統(tǒng)</b>指南

    POE交換機接口詳解

    實現遠程開關控制與亮度調節(jié),節(jié)能高效。 PoE交換機接口與傳統(tǒng)接口的對比 相較于傳統(tǒng)接口,PoE交換機接口在布線、
    發(fā)表于 03-27 17:17

    Telkomsel與華為合作完成EasyAAU千站規(guī)模部署

    近日,印尼領先的電信運營商Telkomsel與華為合作,在2.3GHz頻段完成千站規(guī)模的EasyAAU部署,成功打造巴厘島5G City樣板,逐步向雅加達擴展,為印尼5G網絡建設樹立了新的標桿,也為全球5G發(fā)展提供了寶貴經驗。
    的頭像 發(fā)表于 03-03 11:46 ?1095次閱讀

    行芯完成DeepSeek-R1大模型本地化部署

    近日,行芯正式宣布完成 DeepSeek-R1 大模型本地化部署,實現在多場景、多產品中應用。解鎖“芯”玩法,開啟“芯”未來!
    的頭像 發(fā)表于 02-24 15:17 ?1280次閱讀