Spring Boot整合PF4J:構建動態插拔的組件化架構

前言

在當今快速迭代的軟件開發領域,業務需求的頻繁變更對系統架構的靈活性和可擴展性提出了極高要求。傳統的單體應用架構在面對功能的不斷新增和修改時,往往會陷入代碼臃腫、維護困難、擴展性差的困境。組件化開發,為解決這些問題提供了新的思路,通過實現組件的動態插拔,讓系統能夠更敏捷地響應業務變化。?

1. 背景

在大部分業務場景,微服務拆分不是一個好的選擇。服務拆分帶來有幾方面的挑戰:1)成本增加。微服務單獨部署需要更多資源,包括服務、負載、網絡等;2)應用復雜度增加。微服務需要引入rpc框架,跨服務事務保障,服務鏈路延長耗時處理等;3)應用維護成本增加。微服務調用鏈路延長,在排查問題時,如果沒有日志鏈路工具,整個鏈路追蹤下來是非常耗時的,bug修復維護成本大大增加;4)運維成本增加。多服務器夸鏈路調用,運維成本也會隨之增加。

在綜合考慮性能和成本的情況,會收縮服務應用,抽象出功能齊全的單體應用。單體架構將所有功能模塊打包成一個可執行文件進行部署。這種架構在項目初期,由于功能相對簡單,開發和部署都較為便捷。隨著業務復雜度增加,一些問題會隨之浮現:

  • 通用基礎能力之外,需要為不同客戶提供定制化功能

  • 代碼耦合度越來越高,”屎山“代碼堆積,后來者不敢輕易維護,只能重新寫邏輯,導致不斷增加冗余代碼

  • 某些獨立功能模塊,不隨主線迭代發布

  • 某些不需要的功能,需要下線處理掉

  • 緊急Bug或者功能增加,需要緊急替換服務實現

  • 不同團隊負責不同業務模塊的并行開發

為了應對這些挑戰,組件化開發模式應運而生。

2. 組件化開發,實現系統的敏捷響應?

插件模式開發是一種軟件架構設計模式,允許應用程序通過動態加載和卸載插件來擴展或定制功能,而無需修改主程序的源代碼。這種模式將核心功能與擴展功能分離,使系統具備更高的靈活性、可維護性和可擴展性。

(一)降低維護成本?

在單體架構中,一次小的功能修改可能需要對整個項目進行全面測試,以確保不會影響其他功能。組件化開發后,每個組件都是一個獨立的個體。當需要修改某個功能時,只需對對應的組件進行調整和測試,不會影響到其他組件的正常運行,大大降低了維護的復雜度和測試成本。?

(二)加速功能迭代?

傳統開發模式下,新功能的添加需要重新構建和部署整個應用,流程繁瑣且耗時。采用組件化動態插拔開發,開發人員可以將新功能封裝成獨立的組件,在運行時動態地將其插入到系統中,無需停機和重新部署整個應用,極大地縮短了新功能的上線周期,使系統能夠更快速地響應市場需求。?

(三)提高系統穩定性?

由于組件之間的低耦合性,即使某個組件出現故障,也不會導致整個系統崩潰。其他組件仍然可以正常運行,通過快速定位和修復故障組件,能夠有效提高系統的穩定性和可用性。

(四)適配定制化開發

將定制功能抽象到特定的組件中,通過組件化動態插拔組件,可以很好解決客戶定制化需求。

3. 組件動態插拔框架選型

在Spring框架下,可選擇組件動態插拔框架有:

能力維度OSGiPF4JSpring BrickSpring Plugin CoreSermant
熱部署方式Bundle 動態安裝/卸載JAR 插件熱加載插件包動態安裝/卸載配置驅動,需重啟應用字節碼動態增強
類隔離性? 強隔離(獨立 ClassLoader)?? 需手動配置隔離? 全資源隔離(獨立類加載器)? 無隔離? 宿主應用隔離
Spring 支持度?? 需 Spring DM 適配? 原生友好? 深度集成(Spring Boot 原生開發)? 完全原生?? 部分兼容
通信機制? 原生 ServiceTracker?? 需自建事件總線? 事件總線 + 主程序路由? Bean 直接調用? 不支持跨插件通信
適用場景大型企業應用/IDE中小型業務擴展高隔離業務模塊/SaaS 定制輕量級靜態擴展微服務治理/故障測試
主要限制配置復雜、啟動慢隔離性弱、無服務發現需手動管理資源生命周期無熱插拔、依賴沖突風險無法新增類/字段

結合自身團隊情況以及熱插拔需求,我們選擇基于PF4J作為Springboot應用的插件框架。關于PL4J的相關介紹,可參考官網

PF4J : PF4JPlugin Framework for Javahttps://pf4j.org/其主要突出點包括:

  • 通過獨立類加載器做類隔離,支持運行時熱插拔
  • 核心包很小,類加載運行所需內存資源小
  • 與Spring原生支持性好。

4. 方案實現

4.1 搭建運行框架底座

運行框架底座是spirngboot+JPA+內嵌tomcat的web應用,前端資源直接打包成靜態文件到fat jar中,后端web控制點有權限攔截器和登錄攔截器,數據庫支持MySQL和H2內置數據庫。

父的pom文件定義:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test.sf</groupId><artifactId>sf-flow</artifactId><version>1.0-SNAPSHOT</version><packaging>pom</packaging><modules><module>ingress</module><module>app/standardapp</module><module>app/permissionapp</module><module>layer/framework</module><module>layer/datax-spi</module></modules><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.1</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><jackson.version>2.17.2</jackson.version><protobuf.version>3.25.5</protobuf.version><grpc.version>1.62.2</grpc.version><aws-sdk-java.version>1.12.725</aws-sdk-java.version><springdoc-openapi-ui.version>2.8.4</springdoc-openapi-ui.version><datax-spi-version>1.0-SNAPSHOT</datax-spi-version><hutool.version>5.8.33</hutool.version></properties><dependencyManagement>...</dependencyManagement><profiles><profile><id>dev</id><properties><environment>dev</environment></properties><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><executions><execution><configuration>
<outputDirectory>${basedir}/target/classes</outputDirectory><resources><resource><directory>src/main/resources</directory><filtering>true</filtering><includes><include>**/application-${environment}.properties</include></includes></resource></resources></configuration></execution></executions></plugin></plugins></build></profile>
</profiles></project>

入口ingress的Main函數實現:

@SpringBootApplication(scanBasePackages = { "com.test.sf"
})
@EnableJpaRepositories(basePackages = {"com.test.sf.layer","com.test.sf.a

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

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

相關文章

剃須效率低?電鑄多孔刀網設計如何提升毛發捕捉率

剃須效率低下常源于刀網對毛發的捕捉能力不足——傳統沖壓刀網因孔型單一、邊緣毛刺等問題&#xff0c;導致胡須滑脫或拉扯。而電鑄多孔刀網通過精密工藝革新&#xff0c;將毛發捕捉率提升40%以上。其核心優勢在于三維立體孔型設計與微米級精度控制&#xff0c;以下是技術解析&…

進一步了解git

1、什么是集中式&#xff1f;什么是分布式&#xff1f; SVN&#xff08;集中式&#xff09; 單一中央倉庫&#xff1a;所有代碼和歷史版本集中存儲在中央服務器&#xff0c;用戶本地僅保存當前工作副本。 強依賴網絡&#xff1a;提交、查看歷史等操作需實時連接服務器&#xf…

一、react18+項目初始化

npx create-rect-app 項目名稱配置antd design mobile // 安裝 npm install --save antd-mobile // 在文件中直接引入使用 import { Button } from antd-mobile <Button></Button>更改webpack配置 // 1.安裝必要的包 npm install craco --save-dev // 2.修改pack…

Azure 資源清單

Azure 資源清單 作用前置條件安裝PowerShell 7.0驗證 Azure資源清單安裝配置如果有舊版本&#xff0c;導致新模塊安裝不上&#xff0c;進行強制安裝 PowerShell 登錄到 Azure基本命令輸出詳細信息效果圖展示 作用 官方文檔&#xff1a;https://github.com/microsoft/ARI?tabr…

S11的含義-信號完整性分析

S11的含義: PCB上的互連結構是線性無源的&#xff0c;在傳輸信號時激勵源只有一個&#xff0c;即驅動器發出的信號。如果正弦信號從端口1進入&#xff0c;根據S11定義&#xff0c;S11表示端口1出來的正弦信號和端口1進入的正弦信號的比值。工程上通常把S11稱為回波損耗(Return …

基于OpenCv(開源計算機視覺庫)的圖像旋轉匹配

OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一個開源的計算機視覺和機器學習軟件庫&#xff0c;具有跨平臺特性&#xff0c;廣泛應用于工業檢測、醫療影像分析、自動駕駛、無人機、機器人視覺等多個領域。 本項目解決了圖像模板匹配時的旋轉問題。傳…

Elasticsearch Open Inference API 新增對 Cohere 的 Rerank 3 模型支持

作者&#xff1a;來自 Elastic Serena Chou 及 Max Hniebergall 了解 Cohere reranking&#xff0c;如何將 Cohere 的 Rerank 3 模型與 Elasticsearch 的 open inference API 一起使用&#xff0c;以及 Elastic 在語義 reranking 方面的路線圖。 注&#xff1a;原文在 2024 年 …

九日集訓第六天

目錄 兩個數對之間最大的乘積差 三角形的最大周長 數組拆分 救生艇 擺動排序|| 分發餅干 最少操作使數組遞增 使數組唯一的最小增量 有效三角形的個數 兩個數對之間最大的乘積差 class Solution { public:int maxProductDifference(vector<int>& nums) {so…

【軟件工程】Waitress + Nginx 部署 Python Web 服務

下面是完整的 Windows 系統部署方案,使用 Waitress 作為 WSGI 服務器運行 Python 后端,Nginx 作為反向代理同時提供前端服務: 項目結構 text 復制 下載 myapp/ ├── backend/ # Python后端 │ ├── app.py # Flask應用入口 │ ├──…

JS數據類型檢測方法總結

在 JavaScript 中&#xff0c;數據類型檢測是開發中的常見需求。以下是主要檢測方法及其優缺點&#xff1a; 1. typeof 操作符 最基礎的檢測方式&#xff0c;返回類型字符串&#xff1a; typeof 42; // "number" typeof "hello"; // &qu…

AEO:從搜索引擎到答案引擎,AI時代搜索優化的新戰場

在 ChatGPT、DeepSeek、Google SGE 等生成式AI崛起的時代&#xff0c;搜索正在經歷一場根本性變革&#xff1a; 過去&#xff1a;搜索引擎優化&#xff08;SEO&#xff09; 現在&#xff1a;答案引擎優化&#xff08;AEO&#xff09; 當搜索結果開始由AI直接生成“答案”而非…

搭建Node.js服務器

1.基礎HTTP服務器: 添加了路由處理添加了404錯誤處理添加了服務器錯誤監聽 2.靜態資源服務器: 使用異步文件操作支持目錄自動索引(默認加載 index.html)自動檢測文件類型并設置正確Content-Type更完善的錯誤處理 3.處理GET請求參數 提供了一個HTML表單用于測試使用url模塊…

Linux grep 命令

grep 是 Linux/Unix 系統中用于文本搜索的強大工具&#xff0c;支持基于正則表達式的模式匹配。以下是其詳細用法及實際應用示例&#xff1a; 基本語法 grep [選項] 模式 [文件...]模式&#xff1a;要搜索的字符串或正則表達式。文件&#xff1a;可以是單個文件或多個文件&…

oracle 11g通過rman做備份和還原

ORACLE RMAN增量備份完整恢復測試 1.創建測試環境: 1.1.創建測試表空間 SQL> create tablespace tablespace1 datafile ‘/data/u01/app/oracle/oradata/orcl/tablespace1.dbf’ size 10m; SQL> 1.2.創建測試用戶并指定為默認表空間: SQL> create user user1 iden…

為什么TCP有粘包問題,而UDP沒有

TCP粘包問題源于其面向字節流的設計&#xff0c;而UDP無此問題因其基于數據報的傳輸機制。 &#x1f50d; 一、TCP粘包問題的原因 字節流傳輸特性 TCP將數據視為連續的字節流&#xff0c;而非獨立的消息包。發送端多次寫入的小數據可能被合并為一個TCP段發送&#xff1b;接收端…

ELM:Embodied Understanding of Driving Scenarios

1. ELM 的創新點與核心思路 ELM 的核心在于 “具身理解”(Embodied Understanding),即通過常識與環境交互并進行推理,這一理念適用于自動駕駛車輛、機器人和無人機等多種應用場景。具身智能體(Embodied Agent)需具備四大核心能力:首先,它能夠描述周圍環境,對交通物體的…

實景VR知識科普

實景VR的定義與技術特點 實景VR&#xff0c;即基于真實場景的虛擬現實技術&#xff0c;是通過計算機生成的三維環境&#xff0c;旨在模擬并再現真實世界場景。用戶佩戴VR設備&#xff08;如VR頭盔、手柄等&#xff09;后&#xff0c;能夠沉浸在一個高度仿真的虛擬環境中&#…

CppCon 2016 學習:ITERATOR HAIKU

這組幻燈片講解了 C 中**范圍&#xff08;Ranges&#xff09;和迭代器&#xff08;Iterators&#xff09;**的核心概念&#xff0c;特別是 C14 標準定義的五種迭代器類別&#xff0c;以及范圍的基本使用方式。我幫你理個思路&#xff1a; 1. RANGE-SEQUENCE: 元素范圍&#xf…

開源飛控fmt軟件在環仿真環境搭建

tags: 飛控 fmt開發環境搭建 fmt是國產開源飛控&#xff0c;特點是支持基于模型設計&#xff08;基于simulink仿真&#xff09;&#xff0c;源碼結構目錄較清晰&#xff0c;項目體積較小。 此項目操作系統選擇的是國產實時操作系統rt-thread&#xff0c;也是開源項目。&#…

如何通過AI測試平臺實現自動化缺陷檢測和優化

在數字化轉型加速的今天&#xff0c;軟件質量保證已成為企業競爭力的關鍵要素之一。傳統的手工測試方法面臨著效率低下、成本高昂和覆蓋面有限等挑戰&#xff0c;而AI技術的融入為軟件測試領域帶來了革命性的變化。本文將深入探討如何構建一個完整的AI測試平臺&#xff0c;實現…