<cite id="ffb66"></cite><cite id="ffb66"><track id="ffb66"></track></cite>
      <legend id="ffb66"><li id="ffb66"></li></legend>
      色婷婷久,激情色播,久久久无码专区,亚洲中文字幕av,国产成人A片,av无码免费,精品久久国产,99视频精品3
      網易首頁 > 網易號 > 正文 申請入駐

      手動部署jar包,太low了!動態上傳包熱部署,真爽!

      0
      分享至

      Java精選面試題(微信小程序):5000+道面試題和選擇題,包含Java基礎、并發、JVM、線程、MQ系列、Redis、Spring系列、Elasticsearch、Docker、K8s、Flink、Spark、架構設計、大廠真題等,在線隨時刷題!

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

      定義簡單的接口

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

      public interface Calculator {     int calculate(int a, int b);     int add(int a, int b); }
      該接口的一個簡單的實現

      考慮到用戶實現接口的兩種方式,使用spring上下文管理的方式,或者不依賴spring管理的方式,這里稱它們為注解方式和反射方式。calculate方法對應注解方式,add方法對應反射方式。計算器接口實現類的代碼如下:

      @Service publicclass CalculatorImpl implements Calculator {     @Autowired     CalculatorCore calculatorCore;     /**      * 注解方式      */     @Override     public int calculate(int a, int b) {         int c = calculatorCore.add(a, b);         return c;     }     /**      * 反射方式      */     @Override     public int add(int a, int b) {         returnnew CalculatorCore().add(a, b);     } }

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

      @Service public class CalculatorCore {     public int add(int a, int b) {         return a+b;     } }
      反射方式熱部署

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

      private static String jarAddress = "E:/zzq/IDEA_WS/CalculatorTest/lib/Calculator.jar"; private static String jarPath = "file:/" + jarAddress;

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

      /**  * 熱加載Calculator接口的實現 反射方式,公眾號Java精選  */ public static void hotDeployWithReflect() throws Exception {     URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL(jarPath)}, Thread.currentThread().getContextClassLoader());     Class clazz = urlClassLoader.loadClass("com.nci.cetc15.calculator.impl.CalculatorImpl");     Calculator calculator = (Calculator) clazz.newInstance();     int result = calculator.add(1, 2);     System.out.println(result); }
      注解方式熱部署

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

      直接上代碼:

      /**  * 加入jar包后 動態注冊bean到spring容器,包括bean的依賴  */ public static void hotDeployWithSpring() throws Exception {     Set classNameSet = DeployUtils.readJarFile(jarAddress);     URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL(jarPath)}, Thread.currentThread().getContextClassLoader());     for (String className : classNameSet) {         Class clazz = urlClassLoader.loadClass(className);         if (DeployUtils.isSpringBeanClass(clazz)) {             BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);             defaultListableBeanFactory.registerBeanDefinition(DeployUtils.transformName(className), beanDefinitionBuilder.getBeanDefinition());         }     } }

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

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

      /**  * 讀取jar包中所有類文件  */ public static Set   readJarFile(String jarAddress) throws IOException {     Set classNameSet =  new HashSet<>();     JarFile jarFile = new JarFile(jarAddress);     Enumeration entries = jarFile.entries(); //遍歷整個jar文件     while (entries.hasMoreElements()) {         JarEntry jarEntry = entries.nextElement();         String name = jarEntry.getName();         if (name.endsWith(".class")) {             String className = name.replace(".class", "").replaceAll("/", ".");             classNameSet.add(className);         }     }     return classNameSet; }

      /**  * 方法描述 判斷class對象是否帶有spring的注解  */ public static boolean isSpringBeanClass(Class cla) {     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  */ public static String transformName(String className) {     String tmpstr = className.substring(className.lastIndexOf(".") + 1);     return tmpstr.substring(0, 1).toLowerCase() + tmpstr.substring(1); }
      刪除jar時,需要同時刪除spring容器中注冊的bean

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

      代碼如下:

      /**  * 刪除jar包時 需要在spring容器刪除注入  */ public static void delete() throws Exception {     Set classNameSet = DeployUtils.readJarFile(jarAddress);     URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL(jarPath)}, Thread.currentThread().getContextClassLoader());     for (String className : classNameSet) {         Class clazz = urlClassLoader.loadClass(className);         if (DeployUtils.isSpringBeanClass(clazz)) {             defaultListableBeanFactory.removeBeanDefinition(DeployUtils.transformName(className));         }     } }
      測試

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

      代碼如下:

       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");     DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();     while (true) {         try {               hotDeployWithReflect(); //            hotDeployWithSpring(); //            delete();             } catch (Exception e) {                 e.printStackTrace();                 Thread.sleep(1000 * 10);             }         }

      作者:zhangzhiqiang_0912

      https://blog.csdn.net/zhangzhiqiang_0912

      公眾號“Java精選”所發表內容注明來源的,版權歸原出處所有(無法查證版權的或者未注明出處的均來自網絡,系轉載,轉載的目的在于傳遞更多信息,版權屬于原作者。如有侵權,請聯系,筆者會第一時間刪除處理!

      最近有很多人問,有沒有讀者交流群!加入方式很簡單,公眾號Java精選,回復“加群”,即可入群!

      文章有幫助的話,點在看,轉發吧!

      特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。

      Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

      相關推薦
      熱點推薦
      總有人納悶,王健林就算只剩100億,為啥王思聰花錢還是那么大方

      總有人納悶,王健林就算只剩100億,為啥王思聰花錢還是那么大方

      小光侃娛樂
      2025-12-10 22:10:04
      瓜帥:我不想以被解雇的方式離開,我想好好結束

      瓜帥:我不想以被解雇的方式離開,我想好好結束

      懂球帝
      2025-12-20 15:09:22
      何穗忙完工作一天也不想帶娃!回家換完衣跑去看展覽,當媽后多愁

      何穗忙完工作一天也不想帶娃!回家換完衣跑去看展覽,當媽后多愁

      趕山的姑娘
      2025-12-20 21:23:24
      湘潭一村民組開會決議將“外嫁女”所得法院執行款項從其親屬頭上扣除,村支書:對決議不知情,未簽字批準

      湘潭一村民組開會決議將“外嫁女”所得法院執行款項從其親屬頭上扣除,村支書:對決議不知情,未簽字批準

      紅星新聞
      2025-12-20 00:33:11
      北京阿姨20年守茅臺股票:90萬本金,分紅326萬,成本歸零!

      北京阿姨20年守茅臺股票:90萬本金,分紅326萬,成本歸零!

      趣文說娛
      2025-12-20 18:29:20
      少一人仍不輸,47歲蘭帕德率隊1-1,狂攬48分領跑+領先米堡6分

      少一人仍不輸,47歲蘭帕德率隊1-1,狂攬48分領跑+領先米堡6分

      側身凌空斬
      2025-12-20 22:31:10
      上海迪士尼突發一幕,演出被迫中斷!網友:她還在笑,心太大了

      上海迪士尼突發一幕,演出被迫中斷!網友:她還在笑,心太大了

      環球網資訊
      2025-12-20 09:29:14
      我外交部突然發出警告,如果外媒消息屬實,中日事態將會相當嚴重

      我外交部突然發出警告,如果外媒消息屬實,中日事態將會相當嚴重

      芊芊子吟
      2025-12-20 14:07:18
      人類文明現在只有0.73級,宇宙中的7級文明有多可怕?

      人類文明現在只有0.73級,宇宙中的7級文明有多可怕?

      觀察宇宙
      2025-12-20 20:55:31
      金正恩做出重大舉動,矛頭直指高市早苗

      金正恩做出重大舉動,矛頭直指高市早苗

      回京歷史夢
      2025-12-21 02:40:04
      阿房宮遺址考古取得突破性進展

      阿房宮遺址考古取得突破性進展

      環球網資訊
      2025-12-20 15:09:09
      金毛事件大反轉!為減刑出賣白三姐,20萬轉賬記錄撕開人性遮羞布

      金毛事件大反轉!為減刑出賣白三姐,20萬轉賬記錄撕開人性遮羞布

      魔都姐姐雜談
      2025-12-20 04:48:09
      咖啡再次被關注!醫生發現:高血壓患者經常喝咖啡,或有5改善

      咖啡再次被關注!醫生發現:高血壓患者經常喝咖啡,或有5改善

      牛鍋巴小釩
      2025-12-20 16:45:23
      中央明確規定:從明年起,將對普通高中進行擴招。

      中央明確規定:從明年起,將對普通高中進行擴招。

      百態人間
      2025-12-18 05:00:04
      于東來回應高薪招聘英才:哪怕年薪2000萬都無所謂,給的不是財富,是尊重

      于東來回應高薪招聘英才:哪怕年薪2000萬都無所謂,給的不是財富,是尊重

      都市快報橙柿互動
      2025-12-20 11:30:57
      努諾:丟球過早讓一切變得困難,幾個丟球我們都可以做得更好

      努諾:丟球過早讓一切變得困難,幾個丟球我們都可以做得更好

      懂球帝
      2025-12-21 02:00:07
      王楚欽傳來壞消息:背傷診斷結果曝光!林詩棟17天打3站,不休息

      王楚欽傳來壞消息:背傷診斷結果曝光!林詩棟17天打3站,不休息

      侃球熊弟
      2025-12-20 00:15:03
      池莉:半輩子過去了,自己盡是不體面和不高貴,遍體鱗傷

      池莉:半輩子過去了,自己盡是不體面和不高貴,遍體鱗傷

      尚曦讀史
      2025-12-18 09:46:21
      市監局通報“南極磷蝦油”事件:已成立聯合調查組進駐北京同仁堂(四川)健康藥業有限公司開展調查,已對該企業立案

      市監局通報“南極磷蝦油”事件:已成立聯合調查組進駐北京同仁堂(四川)健康藥業有限公司開展調查,已對該企業立案

      極目新聞
      2025-12-20 19:28:56
      底層無貴人,社交無意義

      底層無貴人,社交無意義

      詩詞中國
      2025-12-19 20:34:22
      2025-12-21 03:40:49
      Java精選
      Java精選
      一場永遠也演不完的戲
      1764文章數 3859關注度
      往期回顧 全部

      科技要聞

      許四清:具身智能的"ChatGPT時刻"還未到來

      頭條要聞

      臺北致4人身亡嫌犯被指是"大陸籍" 蔣萬安回應

      頭條要聞

      臺北致4人身亡嫌犯被指是"大陸籍" 蔣萬安回應

      體育要聞

      我開了20年大巴,現在是一名西甲主帥

      娛樂要聞

      2026央視跨年晚會陣容曝光,豪華陣仗

      財經要聞

      求解“地方財政困難”

      汽車要聞

      嵐圖推進L3量產測試 已完成11萬公里實際道路驗證

      態度原創

      家居
      藝術
      教育
      手機
      公開課

      家居要聞

      高端私宅 理想隱居圣地

      藝術要聞

      投資26億!廣州“獨角獸”的總部大樓,躍出地面!

      教育要聞

      別逼孩子死磕高二數學了!我用3個“懶方法”,讓倒數娃沖進前20

      手機要聞

      vivo X200T再曝,天璣 9400+芯片加持

      公開課

      李玫瑾:為什么性格比能力更重要?

      無障礙瀏覽 進入關懷版 主站蜘蛛池模板: 长春市| 婷婷色综合成人成人网小说 | 久久九九久精品国产免费直播| 91国在线啪精品一区| A片黄色| 亚洲成人AV在线| 亚洲一区二区三区播放| 亚洲色成人一区二区三区小说| 成人午夜视频在线| 久艹AV| 国产色视频一区二区三区| 羞羞影院午夜男女爽爽| 成人午夜免费无码视频在线观看| 久热中文| 亚洲综合久久一区二区| 无码专区男人本色| 香蕉久久av一区二区三区| 亚洲精品国产美女久久久| 中宁县| 国产欧美日韩精品a在线观看| 久久青青草原国产毛片| 高清一区二区三区| 亚洲午夜福利| 人人妻人人妻人人片av| 人妻无码第一区二区三区| 国产xxxx| 东乌珠穆沁旗| 免费看又黄又无码的网站| 黄页网址大全免费观看| 欧亚aV| 一一本无道中文字幕| 亚洲欧美日韩中文字幕一区二区三区| 麻花传媒在线观看免费| 婷婷色av| 国精产品一区一区三区mba下载 | 日韩第四页| 无码专区—va亚洲v天堂麻豆| 国产精品无码素人福利不卡| 激情综合图| 激情五区| 亚洲中文字幕aⅴ天堂|