女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

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

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

3天內不再提示

如何實現動態上傳jar包熱部署

Android編程精選 ? 來源:CSDN技術社區 ? 作者:zhangzhiqiang_0912 ? 2022-06-20 16:57 ? 次閱讀

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

定義簡單的接口

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

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

該接口的一個簡單的實現

考慮到用戶實現接口的兩種方式,使用spring上下文管理的方式,或者不依賴spring管理的方式,這里稱它們為注解方式和反射方式。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的目的是為了驗證在注解模式下,系統可以完整的構造出bean的依賴體系,并注冊到當前spring容器中。CalculatorCore的代碼如下:

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

反射方式熱部署

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

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

并且可以要求用戶填寫jar包中接口實現類的完整類名。接下來系統要把上傳的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,注冊到當前系統的spring容器中。其實,這就是一個類的熱加載+動態注冊的過程。

直接上代碼:

/**
*加入jar包后動態注冊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的注解,如果包含,則將該對象注冊到系統的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的功能。測試函數寫了個死循環,一開始沒有找到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);
}
}

		

					
						


																															

																															

																															

																																			

																																			

																																					

																																					

																																					

原文標題:求求你別再手動部署jar包了,太low了!動態上傳熱部署真的太爽了!

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

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

    關注

    33

    文章

    8939

    瀏覽量

    153193
  • 開發系統
    +關注

    關注

    0

    文章

    38

    瀏覽量

    9989
  • spring
    +關注

    關注

    0

    文章

    340

    瀏覽量

    14878

原文標題:求求你別再手動部署jar包了,太low了!動態上傳熱部署真的太爽了!

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

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    藍牙數據通道空口(數據

    ? 與藍牙廣播相對應,藍牙數據是另一種Bluetooth LE packet。藍牙數據是藍牙數據信道空中的簡稱,表示空中只在藍牙數
    發表于 06-03 10:51

    業務監控—一站式搭建jmeter+telegraf+influxdb+Grafana看板

    jar的JVM指標如何?jar的火焰圖是什么樣的? 對此,只能望洋興嘆。基于以上背景,對jar監控做了一些調研和實戰。 ? ? 二、調研
    的頭像 發表于 05-27 14:40 ?486次閱讀
    業務監控—一站式搭建jmeter+telegraf+influxdb+Grafana看板

    鴻蒙開發實現圖片上傳上傳用戶頭像)

    (FilePicker),實現該能力。通過Picker訪問相關文件,將拉起對應的應用,引導用戶完成界面操作,接口本身無需申請權限。 import picker from \'@ohos.file.picker
    發表于 05-24 23:09

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

    通過endCallback實現中獎消息推送 ? ??安全加固?? 非免認證模式下建議: 添加請求頻率限制 使用HTTPS加密回調 用戶ID做哈希處理 五、常見問題QA ? 部署后訪問顯示空白
    發表于 05-22 20:25

    鋰電池失控原理及安全檢測技術解析

    與未來趨勢 現有設備大多已實現高精度檢測,但仍面臨兩大瓶頸: 動態監測能力不足:現有系統多局限于實驗室環境,難以實時監控車載電池狀態; 多參數耦合分析缺失:-電-機械多場耦合效應對
    發表于 05-12 16:51

    K230D部署模型失敗的原因?

    重現步驟 1.按照教程實現MicroPython 版本部署流程,連接上并將文件放到對應位置后,剛運行就斷開和canmv ide的連接了(此時用的固件版本是圖中推薦的K230D_Zero...
    發表于 03-11 06:19

    《AI Agent 應用與項目實戰》閱讀心得3——RAG架構與部署本地知識庫

    則將檢索到的內容與原始查詢結合,生成最終響應。這種設計使得AI系統能夠突破訓練數據的限制,實現知識的動態更新。書中詳細介紹了RAG的完整工作流程:從數據提取開始,通過文本分割將長文檔切分成適當大小
    發表于 03-07 19:49

    是否可以使用OpenVINO?部署管理器在部署機器上運行Python應用程序?

    使用 OpenVINO?部署管理器創建運行時軟件。 將運行時轉移到部署機器中。 無法確定是否可以在部署機器上運行 Python 應用程
    發表于 03-05 08:16

    使用DRBD和keepalived實現文件實時同步和雙機

    使用DRBD和keepalived實現文件實時同步和雙機
    的頭像 發表于 03-03 17:20 ?331次閱讀

    ComplexHeatmap:個性化圖繪制利器

    ? 圖在很多文章中都有出現,如何畫出讓人眼前一亮的圖?ComplexHeatmap具有非常高的可定制性,無論是圖的顏色搭配、字體樣式,還是聚類方式、注釋信息,每一個細節都能按照
    的頭像 發表于 12-31 11:17 ?273次閱讀
    ComplexHeatmap<b class='flag-5'>包</b>:個性化<b class='flag-5'>熱</b>圖繪制利器

    如何在STM32f4系列開發板上部署STM32Cube.AI,

    已下載STM32Cube.AI擴展,但是無法使用,感覺像是沒有部署AI模型,我是想要通過攝像頭拍照,上傳圖像后,經過開發板處理器進行AI模型處理識別過后,告訴我識別結果,顯示在TFLCD屏幕上
    發表于 11-18 09:39

    springboot的項目如何既要用jar啟動,同時還可以為不同的機房設置不同的配置文件

    作者:京東科技 李意文 1、首先先把配置文件從jar中抽離 示例代碼: ? org.apache.maven.plugins maven-jar-plugin 3.2.0
    的頭像 發表于 10-19 16:48 ?784次閱讀
    springboot的項目如何既要用<b class='flag-5'>jar</b><b class='flag-5'>包</b>啟動,同時還可以為不同的機房設置不同的配置文件

    三行代碼完成生成式AI部署

    LLM加載與推理部署能力,實現了OpenVINO對CNN網絡、生成式模型、LLM網絡主流模型的全面推理支持。
    的頭像 發表于 08-30 16:49 ?677次閱讀
    三行代碼完成生成式AI<b class='flag-5'>部署</b>

    實際上手體驗maven面對沖突Jar的加載規則

    Jar實現功能開發,各種第三方之間可能會存在依賴關系,不同版本的依賴就會可能導致依賴間的相互沖突,進而導致整個項目加載的失敗。 這篇文章主要記錄了本次遇到的問題:即maven在
    的頭像 發表于 08-08 11:22 ?480次閱讀
    實際上手體驗maven面對沖突<b class='flag-5'>Jar</b><b class='flag-5'>包</b>的加載規則

    【AIBOX上手指南】快速部署Llama3

    Firefly開源團隊推出了Llama3部署,提供簡易且完善的部署教程,過程無需聯網,簡單快捷完成本地化部署。點擊觀看Llama3快速部署
    的頭像 發表于 06-06 08:02 ?1124次閱讀
    【AIBOX上手指南】快速<b class='flag-5'>部署</b>Llama3