• 「SpringBrick快速入门指南」:一款基于Spring Boot的高级插件化开发框架


    工作项目中用到了这款插件式开发框架,看了一下网上教程不多,所以打算为大家普及一下这个技术框架,写一些入门教程方便大家学习运用。

    关于 | About

    “Spring-brick”,是一个可以动态扩展系统的框架,最早在2019年开始开发,该框架可以在SpringBoot项目上开发插件功能,开发插件就像开发独立应用一样。

    这里的插件我们可以理解成一个独立的SpringBoot应用,微服务等单体项目。

    技术文档 | Document

    文档如下:https://www.yuque.com/starblues/spring-brick-3.0.0image-20240315154413130

    开源项目 | Project

    开源项目:https://gitee.com/starblues/springboot-plugin-framework-parent.git

    image-20240315154511290

    这个框架除了官方介绍的优点之外,也有它的不足之处,后文我会提出来。

    该框架可以在spring-boot项目上开发出插件功能,在插件中可以和spring-boot使用方式一模一样。使用了本框架您可以实现如下需求:

    • 在插件中,您可以当成一个微型的spring-boot项目来开发,简单易用。
    • 在插件中扩展出系统各种功能点,用于系统灵活扩展,再也不用使用分支来交付不同需求的项目了。
    • 在插件中可以集成各种框架及其各种spring-boot-xxx-starter
    • 在插件中可以定义独立依赖包了,再也不用在主程序中定义依赖包了。
    • 可以完美解决插件包与插件包、插件包与主程序因为同一框架的不同版本冲突问题了。各个插件可以定义同一依赖的不同版本框架。
    • 无需重启主程序,可以自由实现插件包的动态安装部署,来动态扩展系统的功能。
    • 插件也可以不依赖主程序独立集成微服务模块。
    • 您可以丰富想象该框架给您带来哪些迫切的需求和扩展,以实现系统的低耦合、高内聚、可扩展的优点。

    案例 | Demo

    本次演示一个入门小案例,让我带大家快速进入这个框架,上手使用它。这个案例是我自己写的一个便于大家快速入门的案例,不容易出现错误,清晰明了的入门教程。

    项目结构 | Structure

    项目名称: springboot-plugin-framework-example-linghu

    ├─example-main
    │  │  pom.xml
    │  │  
    │  ├─src
    │  │  ├─main
    │  │  │  ├─java
    │  │  │  │  └─com
    │  │  │  │      └─linghu
    │  │  │  │              MainApp.java
    │  │  │  │              
    │  │  │  └─resources
    │  │  │          application.yml
    │     
    └─example-plugins-basic
        │  pom.xml
        │  
        ├─src
        │  ├─main
        │  │  ├─java
        │  │  │  └─com
        │  │  │      └─linghu
        │  │  │          ├─controller
        │  │  │          │      ExampleController.java
        │  │  │          │      ExamplePlugin.java
        │  │  │          │      
        │  │  │          └─plugin
        │  │  └─resources
        │  │          application.yml
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    这个项目分为两个部分:

    • 主程序-example-main
    • 插件程序-example-plugins-basic

    我们的目的是运行主程序,然后执行插件程序里的业务,这样我们就可以专注开发插件程序了,可以不断根据业务的不同接入不同的插件程序,而不用去动主程序的代码,这就是我们说的 高内聚、低耦合、可扩展

    分好类以后我们开始接下来的具体工作。

    我们的工作分为两个部分:

    • 主程序配置集成 | Settings
    • 插件配置集成 | Settings

    主程序配置集成 | Settings

    我们说了主程序实际上就是上面 example-main部分。

    引入框架依赖 | Framework

    引入框架依赖:

    <dependency>
                <groupId>com.gitee.starbluesgroupId>
                <artifactId>spring-brickartifactId>
                <version>3.1.0version>
     dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    具体主程序的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/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0modelVersion>
        <parent>
            <groupId>com.linghugroupId>
            <artifactId>springboot-plugin-framework-example-linghuartifactId>
            <version>1.0-SNAPSHOTversion>
        parent>
    
        <artifactId>example-mainartifactId>
    
        <properties>
            <maven.compiler.source>8maven.compiler.source>
            <maven.compiler.target>8maven.compiler.target>
            <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        properties>
    
        <dependencies>
            <dependency>
                <groupId>com.gitee.starbluesgroupId>
                <artifactId>spring-brickartifactId>
                <version>3.1.0version>
            dependency>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
    
        dependencies>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    在配置文件加入配置 | Yaml

    这里的yaml文件配置主要是让将插件程序接入到主程序中

    plugin:
      runMode: dev
      mainPackage: com.linghu
      pluginPath:
    #    这里集成了一个插件程序example-plugins-basic模块
        - ~\example-plugins-basic
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    需要注意的是上面的 mainPackage表示主程序类的路径。pluginPath则是我们插件的相对路径地址。

    - ~\example-plugins-basic中的 ~\表示相对路径地址; example-plugins-basic则是我们的插件名称。

    完整的yml配置则是:

    server:
      port: 8080
    
    plugin:
      runMode: dev
      mainPackage: com.linghu
      pluginPath:
    #    这里集成了一个插件程序example-plugins-basic模块
        - ~\example-plugins-basic
    spring:
      mvc:
        pathmatch:
          matching-strategy: ant_path_matcher
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    SpringBoot启动类改引导类 | Change

    这个改动发生在主程序的启动类上

    package com.linghu;
    
    import com.gitee.starblues.loader.launcher.SpringBootstrap;
    import com.gitee.starblues.loader.launcher.SpringMainBootstrap;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * @author linghu
     * @date ${DATE} ${TIME}
     */
    @SpringBootApplication
    public class MainApp implements SpringBootstrap {
        public static void main(String[] args) {
            // 该处使用 SpringMainBootstrap 引导启动
            SpringMainBootstrap.launch(MainApp.class, args);
        }
    
        @Override
        public void run(String[] args) throws Exception {
            // 在该实现方法中, 和 SpringBoot 使用方式一致
            SpringApplication.run(MainApp.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    这里为啥要这么改?后续我会出文章解释,剖析源码。

    插件配置集成 | Settings

    插件程序主要是指:example-plugins-basic部分

    引入依赖 | XML
    
    
    <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starterartifactId>
      <version>${和主程序一致的springboot版本}version>
    dependency>
    
    
    <dependency>
      <groupId>com.gitee.starbluesgroupId>
      <artifactId>spring-brick-bootstrapartifactId>
      <version>${latest.version}version>
    dependency>
    
    
    
    <dependency>
      <groupId>主程序的 groupIdgroupId>
      <artifactId>主程序的 artifactIdartifactId>
      <version>主程序 versionversion>
      <scope>providedscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    上面是个引入模版,大家引入以后还要进行修改,下面是我修改的我的完整依赖:

    
    <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/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0modelVersion>
        <parent>
            <groupId>com.linghugroupId>
            <artifactId>springboot-plugin-framework-example-linghuartifactId>
            <version>1.0-SNAPSHOTversion>
        parent>
    
        <artifactId>example-plugins-basicartifactId>
    
        <properties>
            <maven.compiler.source>8maven.compiler.source>
            <maven.compiler.target>8maven.compiler.target>
            <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        properties>
    
        <dependencies>
            
            
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starterartifactId>
                <version>2.7.9version>
            dependency>
    
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.bootgroupId>
                        <artifactId>spring-boot-starter-webartifactId>
                    exclusion>
                exclusions>
            dependency>
    
    
            
            <dependency>
                <groupId>com.gitee.starbluesgroupId>
                <artifactId>spring-brick-bootstrapartifactId>
                <version>3.1.0version>
            dependency>
    
            
            
            <dependency>
                <groupId>com.linghugroupId>
                <artifactId>example-mainartifactId>
                <version>1.0-SNAPSHOTversion>
                <scope>providedscope>
            dependency>
        dependencies>
    
    
        <build>
            <plugins>
                <plugin>
                    <groupId>com.gitee.starbluesgroupId>
                    <artifactId>spring-brick-maven-packagerartifactId>
                    <version>3.1.0version>
                    <configuration>
                        
                        <mode>devmode>
                        
                        <pluginInfo>
                            
                            <id>example-plugins-basicid>
                            
                            <bootstrapClass>com.linghu.controller.ExamplePluginbootstrapClass>
                            
                            <version>1.0.0-SNAPSHOTversion>
                        pluginInfo>
                    configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackagegoal>
                            goals>
                        execution>
                    executions>
                plugin>
            plugins>
        build>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    定义插件引导类 | Class

    这个引导类是加在插件里的主类里的,不要搞错了。

    package com.linghu.controller;
    
    import com.gitee.starblues.bootstrap.SpringPluginBootstrap;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * @author linghu
     * @date 2024/3/15 9:55
     */
    @SpringBootApplication
    public class ExamplePlugin extends SpringPluginBootstrap {
        public static void main(String[] args) {
            new ExamplePlugin().run(args);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    定义插件main入口类, 继承SpringPluginBootstrap类, 然后在main函数中实例化当前引导类,并执行run方法即可。

    配置Maven打包插件 | Maven

    其实这一步工作我已经在上面提到了,也就是在引入依赖部分提供了。

    
        <build>
            <plugins>
                <plugin>
                    <groupId>com.gitee.starbluesgroupId>
                    <artifactId>spring-brick-maven-packagerartifactId>
                    <version>3.1.0version>
                    <configuration>
                        
                        <mode>devmode>
                        
                        <pluginInfo>
                            
                            <id>example-plugins-basicid>
                            
                            <bootstrapClass>com.linghu.controller.ExamplePluginbootstrapClass>
                            
                            <version>1.0.0-SNAPSHOTversion>
                        pluginInfo>
                    configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackagegoal>
                            goals>
                        execution>
                    executions>
                plugin>
            plugins>
        build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    新增Controller接口API | API

    其实这个接口我们就加在插件程序里就行了

    package com.linghu.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author linghu
     * @date 2024/3/15 9:58
     */
    
    @RestController
    @RequestMapping("/example")
    public class ExampleController {
        @GetMapping
        public String hello(){
            return "hello";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    注意一下Controller位置,放错了很容易导致后续Controller加载不到主程序的:

    image-20240315163409936

    编译打包插件 | JAR

    这里打包有两种方法:

    • 插件使用maven命令:mvn clean package进行编译
    • 通过Maven插件、先点击clean、在点击package

    我用的第二种方法打包,如图:

    image-20240315163849557

    打包完成以后,观察target文件下会出现jar包:

    image-20240315163925679

    启动测试 | Main

    这个测试是直接启动主程序的

    • 启动主程序main, 日志中出现如下关键内容,说明集成插件成功

    image-20240315164322248

    image-20240315164443221

    如上我们还知道了如下信息,那就是我们请求测试的接口地址为:

    http://127.0.0.1:8080/plugins/example-plugins-basic/

    打开浏览器,访问: http://127.0.0.1:8080/plugins/example-plugins-basic/example出现下图说明访问接口测试成功。

    image-20240315164521738

    Demo案例Git地址 | Gitee

    这个教程属于入门级别的,没有对源码,原理展开讲解,后续有时间会接着更的,这里主要是教大家快速上手,遇到不懂的,欢迎评论区提出。

    完整项目demo:

    《SpringBrick-springboot-plugin-framework-example-linghu》

    项目下载以后记得要用Maven插件打一下jar包,可以直接运行:

    mvn clean package进行编译~

  • 相关阅读:
    使用高数值孔径透镜进行脉冲聚焦
    什么是零代码?无代码和低代码开发平台该如何抉择?
    python mysql语句中有单引号执行的报错处理方式
    代码的艺术-Writing Code Like a Pianist
    ESP8266-Arduino编程实例-74HC595位移寄存驱动
    Hudi第一章:编译安装
    一些css记录
    全局变量报错:\Output\STM32.axf: Error: L6218E: Undefined symbol
    【无标题】
    百度松果菁英班——机器学习实践一:海量文件遍历
  • 原文地址:https://blog.csdn.net/weixin_43891901/article/details/136744605