背景
在當下後端市場,還是以spring-boot為核心架構進行系統開發,本架構可以在spring-boot系統上進行插件式的開發,将插件當做一個mini版本的spring-boot進行系統擴充開發,可以解決如下痛點:
- 在To-B系統場景中,不同甲方會有不同的需求,在不打分支和改動系統核心代碼的前提下,可以在插件中進行擴充開發特定功能,不同甲方使用不同插件,完美解決非核心系統的擴充功能開發,例如擴充中台系統的不同需求。
- 在To-C系統場景中,可以在主程式通過定義java-interface,在插件中做不同實作,來達到動态擴充系統功能。
- 在開發中,由于引入了不同版本的依賴,導緻系統無法運作,本架構可以完美解決在不同插件中定義不同版本的依賴,從底層進行隔離,以解決引入不同版本依賴沖突的問題。比如可以完美解決系統同時連接配接資料庫mysql-5和mysql-8版本。
- 在開發中,不同插件依賴不同架構的功能,可以按需引入。比如在插件A引入連接配接mysql、在插件B引入連接配接elasticsearch、在插件C引入連接配接oracle。
- 在插件中,可以任意內建不同的非web類型的springboot-xx-starter,然後将不同插件功能組裝起來,以達到一個統一對外提供服務的完整系統,實作系統組裝化、插拔化開發。
- 在不重新開機主程式的前提下,對插件進行動态的安裝、解除安裝、啟動、停止。
介紹
該架構可以在spring-boot項目上開發出插件功能,在插件中可以和spring-boot使用方式一模一樣。使用了本架構您可以實作如下需求:
- 在插件中,您可以當成一個微型的spring-boot項目來開發,簡單易用。
- 在插件中擴充出系統各種功能點,用于系統靈活擴充,再也不用使用分支來傳遞不同需求的項目了。
- 在插件中可以內建各種架構及其各種spring-boot-xxx-starter。
- 在插件中可以定義獨立依賴包了,再也不用在主程式中定義依賴包了。
- 可以完美解決插件包與插件包、插件包與主程式因為同一架構的不同版本沖突問題了。各個插件可以定義同一依賴的不同版本架構。
- 無需重新開機主程式,可以自由實作插件包的動态安裝部署,來動态擴充系統的功能。
- 插件也可以不依賴主程式獨立內建微服務子產品。
- ~~~等等,您可以豐富想象該架構給您帶來哪些迫切的需求和擴充,以實作系統的低耦合、高内聚、可擴充的優點。
特性
- 簡化了架構的內建步驟,更容易上手。
- 插件開發更加貼近spring-boot原生開發。
- 支援兩種模式開發: 隔離模式、共享模式, 可自主根據需要靈活選擇使用。
- 使用Maven打包插件,支援對插件的自主打包編譯。目前支援:
- 開發打包:将插件打包成開發環境下的插件(僅需打包一次)。
- 生産打包:将插件打包成一個jar、zip、檔案夾等。
- 自主的開發的類加載器,支援插件定義各種的依賴jar包。
- 在插件中可以內建各種架構及其各種spring-boot-xxx-starter,比如內建mybatis、mybatis-plus、spring-jpa等。
- 動态安裝、解除安裝、啟動、停止插件。
- 主程式和插件類隔離, 有效避免主程式與插件、插件與插件之間的類沖突。
架構
主程式配置內建
1. 引入架構依賴
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>spring-brick</artifactId>
<version>${latest.version}</version>
</dependency>
2. 在配置檔案加入配置
plugin:
runMode: dev
mainPackage: com.gitee.starblues.example
pluginPath:
- D://project//plugins(替換為自己環境下插件目錄)
- 配置說明:
runMode: 運作模式, 開發環境: dev; 生産環境: prod。dev環境下,隻适用于在idea環境下開發調試,prod環境隻能加載打包的插件,比如jar、zip等,插件打包詳見: 插件打包詳細說明
mainPackage: 主程式掃描的包名。
pluginPath: 插件目錄或者插件上級目錄,可配置多個。
- 詳細配置見:https://www.yuque.com/starblues/iuyk4y/pm8x4g
3. 改造 Spring-Boot 啟動類
- 在main類中實作架構引導類SpringBootstrap,在run方法中使用和SpringBoot啟動方式一緻的實作。
- 在main方法中使用SpringMainBootstrap進行引導啟動。具體實作如下:
import com.gitee.starblues.loader.launcher.SpringMainBootstrap;
import com.gitee.starblues.loader.launcher.SpringBootstrap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements SpringBootstrap {
public static void main(String[] args) {
// 該處使用 SpringMainBootstrap 引導啟動
SpringMainBootstrap.launch(Application.class, args);
}
@Override
public void run(String[] args) throws Exception {
// 在該實作方法中, 和 SpringBoot 使用方式一緻
SpringApplication.run(Application.class, args);
}
}
4. 打包主程式
- 主程式使用maven指令:mvn clean install進行打包
插件配置內建
1. 引入依賴
<!-- spring-boot-starter依賴 -->
<!--建議将spring-boot-starter依賴放到第一個位置, 以防止出現依賴沖突導緻無法啟動插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${和主程式一緻的springboot版本}</version>
</dependency>
<!-- spring-brick-bootstrap依賴 -->
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>spring-brick-bootstrap</artifactId>
<version>${latest.version}</version>
</dependency>
<!-- 主程式依賴 -->
<!-- 将主程式以 provided 方式依賴到插件中 -->
<dependency>
<groupId>主程式的 groupId</groupId>
<artifactId>主程式的 artifactId</artifactId>
<version>主程式 version</version>
<scope>provided</scope>
</dependency>
2. 定義插件引導類
注意:插件包名不能和主程式包名一緻,如需一緻,需遵循:插件包名範圍小于等于主程式包名。
詳細規則可見:https://www.yuque.com/starblues/spring-brick-3.0.0/siet7b
- 定義插件main入口類, 繼承SpringPluginBootstrap類, 然後在main函數中執行個體化目前引導類,并執行run方法即可。實作如下:
import com.gitee.starblues.bootstrap.SpringPluginBootstrap;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ExamplePlugin extends SpringPluginBootstrap {
public static void main(String[] args) {
new ExamplePlugin().run(args);
}
}
3. 配置Maven打包插件
- 使用架構自帶的打包插件,對插件包進打包。
- 将如下配置加入到插件的maven的 pom.xml 中
<build>
<plugins>
<plugin>
<groupId>com.gitee.starblues</groupId>
<artifactId>spring-brick-maven-packager</artifactId>
<version>${latest.version}</version>
<configuration>
<!--目前打包模式為: 開發模式-->
<mode>dev</mode>
<!--插件資訊定義-->
<pluginInfo>
<!--插件id-->
<id>plugin-example</id>
<!--插件入口類, 定義說明見: 定義插件入口類-->
<bootstrapClass>com.gitee.starblues.example.ExamplePlugin</bootstrapClass>
<!--插件版本号-->
<version>1.0.0-SNAPSHOT</version>
</pluginInfo>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 詳細打包插件說明見: https://www.yuque.com/starblues/iuyk4y/tfxx2b
4. 新增 Controller 接口
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/example")
public class ExampleController {
@GetMapping
public String hello(){
return "hello";
}
}
5. 編譯插件
- 插件使用maven指令:mvn clean package進行編譯
啟動測試
- 啟動主程式main, 日志中出現如下關鍵内容,說明內建插件成功
c.g.s.i.operator.DefaultPluginOperator : 插件加載環境: dev
c.g.s.core.PluginLauncherManager : 插件[[email protected]]加載成功
c.g.s.b.p.web.PluginControllerProcessor : 插件[plugin-example]注冊接口: {GET [/plugins/module1/example]}
c.g.s.core.PluginLauncherManager : 插件[[email protected]]啟動成功
c.g.s.i.operator.DefaultPluginOperator : 插件初始化完成
- 打開浏覽器,通路接口: http://127.0.0.1:8080/plugins/plugin-example/example 進行測試是否能通路成功。