精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

    文章

    8526

    瀏覽量

    150861
  • 開發系統
    +關注

    關注

    0

    文章

    38

    瀏覽量

    9672
  • spring
    +關注

    關注

    0

    文章

    338

    瀏覽量

    14312

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

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

收藏 人收藏

    評論

    相關推薦

    功率器件設計基礎(六)——瞬態測量

    功率半導體熱設計是實現IGBT、碳化硅SiC高功率密度的基礎,只有掌握功率半導體的設計基礎知識,才能完成精確設計,提高功率器件的利用率,降低系統成本,并保證系統的可靠性。功率器件
    的頭像 發表于 11-26 01:02 ?534次閱讀
    功率器件<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 ?416次閱讀
    springboot的項目如何既要用<b class='flag-5'>jar</b><b class='flag-5'>包</b>啟動,同時還可以為不同的機房設置不同的配置文件

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

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

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

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

    請問OPA462如何實現自動的關斷?

    請問:看OPA462的數據手冊,Status-flag引腳是狀態輸出引腳,E/D引腳是使能引腳,這兩個引腳如何連接,實現自動的關斷呢?
    發表于 07-30 07:06

    如何進行電池PACK失控防護?

    隨著純電動汽車快速普及,保有量大幅增加,電池PACK起火、自燃、爆炸事件頻發,失控成為影響動力電池安全的最大誘因。 電池會起火,原因主要包括電池部件老化、外部碰撞、高溫天氣、電池失控、高負荷等五
    的頭像 發表于 07-08 11:12 ?463次閱讀
    如何進行電池<b class='flag-5'>包</b>PACK<b class='flag-5'>熱</b>失控防護?

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

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

    鴻蒙實戰開發-本地部署、SmartPerf 編譯部署指導文檔

    編譯環境搭建 注意:在linux編譯環境安裝時以root或者其他 sudo 用戶身份運行下面的命令。 node 環境安裝 下載Node js安裝(windows推薦, linux跳過此步驟) 從
    發表于 05-09 14:23

    基于OpenCV DNN實現YOLOv8的模型部署與推理演示

    基于OpenCV DNN實現YOLOv8推理的好處就是一套代碼就可以部署在Windows10系統、烏班圖系統、Jetson的Jetpack系統
    的頭像 發表于 03-01 15:52 ?1429次閱讀
    基于OpenCV DNN<b class='flag-5'>實現</b>YOLOv8的模型<b class='flag-5'>部署</b>與推理演示

    什么是動態線程池?動態線程池的簡單實現思路

    因此,動態可監控線程池一種針對以上痛點開發的線程池管理工具。主要可實現功能有:提供對 Spring 應用內線程池實例的全局管控、應用運行時動態變更線程池參數以及線程池數據采集和監控閾值報警。
    的頭像 發表于 02-28 10:42 ?595次閱讀

    鴻蒙開發【編譯構建】講解

    生成HAP、HAR和JAR。 Rebuild Project 對工程中各個模塊進行Clean操作后,重新進行構建,生成對應的HAP。 Clean Project 清除構建過程中的緩存文件,以及構建生成
    發表于 02-27 17:41

    塑料增強超薄小外形封裝SOT1220-4程序信息

    電子發燒友網站提供《塑料增強超薄小外形封裝SOT1220-4程序信息.pdf》資料免費下載
    發表于 02-20 10:29 ?0次下載
    塑料<b class='flag-5'>熱</b>增強超薄小外形封裝SOT1220-4程序<b class='flag-5'>包</b>信息

    SpringBoot項目Jar加密防止反編譯方案

    最近項目要求部署到其他公司的服務器上,但是又不想將源碼泄露出去。要求對正式環境的啟動進行安全性處理,防止客戶直接通過反編譯工具將代碼反編譯出來。
    的頭像 發表于 12-12 14:04 ?1251次閱讀
    SpringBoot項目<b class='flag-5'>Jar</b><b class='flag-5'>包</b>加密防止反編譯方案

    jrebel和idea部署優勢

    JRebel 和 IntelliJ IDEA 是兩個常用的開發工具,它們可以提供熱部署的功能,極大地提高了開發效率。下面將詳細介紹 JRebel 和 IntelliJ IDEA 部署的優勢。 提高
    的頭像 發表于 12-03 15:16 ?742次閱讀