輕量級 ioc 框架 loveqq,支持接口上傳 jar 格式的 starter 啟動器并支持熱加載其中的 bean

輕量級 ioc 框架 loveqq,支持接口上傳 jar 格式的 starter 啟動器并支持熱加載其中的 bean


熱加載 starter 啟動器代碼示例:

package com.kfyty.demo;import com.kfyty.loveqq.framework.boot.K;
import com.kfyty.loveqq.framework.boot.context.ContextRefresher;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.BootApplication;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;
import com.kfyty.loveqq.framework.core.autoconfig.condition.annotation.ConditionalOnMissingBean;
import com.kfyty.loveqq.framework.core.lang.JarIndexClassLoader;
import com.kfyty.loveqq.framework.core.utils.IOC;
import com.kfyty.loveqq.framework.web.core.annotation.GetMapping;
import com.kfyty.loveqq.framework.web.core.annotation.RequestMapping;
import com.kfyty.loveqq.framework.web.core.annotation.RestController;
import com.kfyty.loveqq.framework.web.core.autoconfig.annotation.EnableWebMvc;
import com.kfyty.loveqq.framework.web.core.multipart.MultipartFile;
import lombok.extern.slf4j.Slf4j;import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.security.cert.Extension;
import java.util.Collections;
import java.util.UUID;
import java.util.jar.JarFile;@Slf4j
@EnableWebMvc
@RestController
@BootApplication
@RequestMapping(expose = true)                  // 自動暴露 public 方法為 POST http 接口
public class Main {@Autowiredprivate Extension extension;/*** 測試接口*/@GetMappingpublic String sayHello() {return extension.getId();}/*** 加載插件** @param jar jar 包 啟動器* @return 上傳后的 jar 包絕對路徑,卸載啟動器時需要提供該返回值*/public String loadPlugin(MultipartFile jar) throws Exception {// 保存到本地String filePath = "D:\\temp\\jar\\" + UUID.randomUUID().toString().replace("-", "") + "\\" + jar.getOriginalFilename();File jarFile = new File(filePath);jar.transferTo(jarFile);// 添加到框架 ClassLoaderJarIndexClassLoader classLoader = (JarIndexClassLoader) IOC.class.getClassLoader();classLoader.addJarIndex(Collections.singletonList(new JarFile(jarFile)));// 刷新上下文ContextRefresher.refresh(IOC.getApplicationContext());return jarFile.getAbsolutePath();}/*** 卸載啟動器** @param jarPath {@link #loadPlugin(MultipartFile)} 的返回值*/public String unloadPlugin(String jarPath) throws Exception {// 構建 File 對象File jarFile = new File(jarPath);// 從框架 ClassLoader 移除JarIndexClassLoader classLoader = (JarIndexClassLoader) IOC.class.getClassLoader();classLoader.removeJarIndex(Collections.singletonList(new JarFile(jarFile)));// 刷新上下文ContextRefresher.refresh(IOC.getApplicationContext());return "ok";}public static void main(String[] args) throws Exception {K.run(Main.class, args);}/*** 默認實現*/@Component@ConditionalOnMissingBean(Extension.class)public static class DefaultExtension implements Extension {@Overridepublic String getId() {return "default";}@Overridepublic boolean isCritical() {return false;}@Overridepublic byte[] getValue() {return new byte[0];}@Overridepublic void encode(OutputStream out) throws IOException {}}
}

然后,新建一個項目,添加如下類:

package com.kfyty.graal.example;import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component;import java.io.IOException;
import java.io.OutputStream;
import java.security.cert.Extension;/*** 動態加載示例實現*/
@Component
public class ExampleExtension implements Extension {@Overridepublic String getId() {return "example";}@Overridepublic boolean isCritical() {return false;}@Overridepublic byte[] getValue() {return new byte[0];}@Overridepublic void encode(OutputStream out) throws IOException {}
}

并在 k.factories 中添加:

com.kfyty.loveqq.framework.core.autoconfig.annotation.EnableAutoConfiguration=com.kfyty.graal.example.ExampleExtension

然后打成 jar 包,就是一個啟動器了。

接著啟動第一段代碼的 main 方法后:

先訪問:http://localhost:8080/sayHello,將返回 default

然后使用 postman 上傳啟動器 jar 包:http://127.0.0.1:8080/loadPlugin,此時將動態加載上傳的啟動器,并刷新 ioc 容器

然后再訪問:http://localhost:8080/sayHello,將返回 example,原因是加載了新的啟動器,條件注解生效,實現類變化了!

然后再訪問:http://127.0.0.1:8080/unloadPlugin,將第二步的返回值作為入參傳入,此時將卸載啟動器,并刷新 ioc 容器

然后再訪問:http://localhost:8080/sayHello,將返回 default,原因是卸載了之前加載的啟動器,條件注解生效,實現類又變化了!

從而實現了啟動器的熱加載,感興趣的同學可以試一下。

gitee/github/gitcode: loveqq-framework

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/909629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/909629.shtml
英文地址,請注明出處:http://en.pswp.cn/news/909629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

圖論----4.實現 Trie (前綴樹)

題目鏈接 /** Trie前綴樹基本結構: (多叉單詞查找樹)每個Trie中包含一個Trie數組與一個結束標識 Trie[] children Trie數組,每個節點都可存放一個Trie,其索引代表該節點對應的字符。 boolean isEnd 結束標識, 代表當前節點是否是一個完整單詞的結尾巴 前綴樹insert流程: 計算第…

DELL R730XD服務器調整風扇轉速

注意: 進入iDRAC的Web管理界面,左側iDRAC設置->網絡->IPMI設置,勾選啟用LAN上的IPMI。使用ipmitool調整,服務器電源斷開后就會失效,如果想要永久生效,就在服務器端寫一個開機自啟動腳本。先關閉風扇…

從C++編程入手設計模式——策略設計模式

從C編程入手設計模式——策略設計模式 ? 在我們平時寫程序的過程中,經常會遇到這樣的情況:一個對象的某個功能可以有多種實現方式,而且可能會根據不同的場景切換這些方式。比如一只動物可以發出不同的叫聲,一個排序器可以使用不…

網頁中調用自定義字體可以通過 ?CSS? 的 @font-face 規則實現

以下是詳細方法: ?1. 使用系統默認字體? 如果只是希望指定字體,可以直接使用 font-family: body { font-family: "Microsoft YaHei", "PingFang SC", sans-serif; /* 中英文適配 */ } ?2. 使用自定義字體&…

[CVPR 2025] DeformCL:基于可變形中心線的3D血管提取新范式

CVPR 2025 | DeformCL:基于可變形中心線的3D血管提取新范式 論文信息 標題:DeformCL: Learning Deformable Centerline Representation for Vessel Extraction in 3D Medical Image作者:Ziwei Zhao, Zhixing Zhang, Yuhang Liu, 等單位&…

BeckHoff <---> Keyence (LJ-X8000) 2D相機 Profinet 通訊

目錄 ?編輯 一、 設備介紹 1、產品特點 2、控制器選擇 3、應用領域 二、PLC通訊接口配置 1、PLC添加GSDML文件 2、定義輸入3、變量實例化 3、定義輸出變量實例化 三、設備通訊接口數據類型定義 1、定義全局結構體數據 2、定義 INput Decode結構體數據 四、通訊…

electron在單例中實現雙擊打開文件,并重復打開其他文件

單實例的思路 首次通過雙擊文件打開應用 將filePath傳給render 使用中的應用,再次雙擊打開文件 第一個實例創建時,同時創建一個通信服務器net.createServer()第二個實例創建時,連接第一個服務器net.createConnection()將再次打開的filePath傳…

一、基礎架構層:高性能引擎基石

1. ECS架構工業級實現 // EnTT實戰示例:導彈系統組件定義 struct Position { vec3 value; }; struct Velocity { vec3 value; }; struct ExplodeWhen { float distance; };entt::registry registry;// 實體創建與組件綁定 auto missile registry.create(); regist…

rockylinuxapache和Linux服務配置

目錄 apache nginx 反向代理配置[rootk8s2 ~]# [rootk8s2 ~]# cat /etc/nginx/conf.d/webserver.confserver { listen 80; server_name www.sxy1.com; location / { root /var/www/html; index index.html; } location /py/{ …

ai 幻覺

ai幻覺: 感知人類觀察者不存在或無法感知的模式或對象,從而產生無意義或完全不準確的輸出 有時 AI 算法會生成并非基于訓練數據的輸出結果,繼而被轉換器錯誤解碼或不遵循任何可識別的模式。換句話說,它會在給出響應時“產生幻覺” 致因:訓練…

freeRTOS移植實驗

提示:文章 文章目錄 前言一、背景第6章節 二、2.12.2 三、3.1 總結 前言 前期疑問: 本文目標: 一、背景 在家里先使用野火網盤資料里的freeRTOS源碼,網盤里是v9.0.0。 J:\野火\STM32F103ZET6_霸道開發板\A盤(資料盤…

食品加工溫控場景:PROFIBUS轉MODBUS的溫控表連接規范

在現代的工業自動化領域里,實現不同通信協議設備間無縫對接的技術日益受到重視。這不僅關乎系統整合性和效率的提升,更是實現復雜工業過程自動化的必經之路。特別是在眾多的通信協議中,MODBUS和PROFIBUS這兩種廣泛使用的協議因其各自的優勢而…

【動態規劃】回文串(二)

📝前言說明: 本專欄主要記錄本人的動態規劃算法學習以及LeetCode刷題記錄,按專題劃分每題主要記錄:(1)本人解法 本人屎山代碼;(2)優質解法 優質代碼;&…

Ubuntu22.04.5 桌面版然后安裝 VMware 17

安裝 VMware 需要 GCC 12版本 標題通過 PPA 安裝 這是最簡單的方法,適用于大多數 Ubuntu 版本。 步驟 1:添加 PPA 倉庫 sudo apt update sudo apt install software-properties-common sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt…

深入解析 MySQL 架構:從基礎到高級

MySQL 是一款廣泛使用的開源關系型數據庫管理系統,以其高性能、可靠性和靈活性而聞名。無論是小型創業公司還是大型企業,MySQL 都是許多應用程序的首選數據庫解決方案。本文將深入探討 MySQL 的架構設計,幫助讀者更好地理解其內部工作機制&am…

BACnet協議移植適配實現BACnet/IP和BACnet MSTP相關功能

1、從GitHub或者其他網站下載最新的協議棧源碼 源碼結構如圖所示: 其中src是協議棧源碼,可直接拿來使用,apps里面是一些功能的應用示例,有BACnet IP,BACnet MSTP,BACnet Router等功能。 2、協議棧移植完成…

Ubuntu 22.04.1 LTS 離線安裝Docker(最快方法,僅需一個壓縮文件和兩個腳本)

作者親測:親測有效無bug。 利用ubuntu22.04下載完docker-27.4.1.tgz,然后按照下面方法安裝。選擇sudo方法。 tips:這個ubuntu22.04是遷移后的服務器的版本,不是遷移前的版本。 下載 下載地址 : https://download.docker.com/linux/static/stable/x86_…

Tkinter --按鈕點擊事件應用場景

第二章 事件處理 目錄 第二章 事件處理 四、事件處理 4.1 按鈕點擊事件 4.1.1信息展示類場景 1. 靜態文本說明 ?編輯 2. 動態狀態顯示 4.1.2.界面美化與裝飾 1. 圖像 / 圖標展示 ?編輯 2. 分隔與布局輔助 4.1.3 交互反饋與提示 1. 操作結果提示 2. 幫助與說明文本…

計算機網絡學習筆記:TCP流控、擁塞控制

文章目錄 前言一、TCP流量控制1.1、案例:三次流量控制1.2、持續計時器 二、TCP擁塞控制2.1、擁塞控制的指標2.2、慢開始算法和擁塞避免算法2.3、快重傳算法和快恢復算法2.4、練習 三、TCP擁塞控制與網際層擁塞控制總結 前言 TCP協議中的流量和擁塞,是兩個…

【Linux】Tomcat搭建

前言 Tomcat Tomcat 服務器是一個免費的開放源代碼的Web 應用服務器,屬于輕量級應用服務器,在中小型系統和并發訪問用戶不是很多的場合下被普遍使用,是開發和調試JSP 程序的首選。 JSP JSP是一種跨平臺的動態網頁技術標準,可以…