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

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

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

关于 | About

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

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

技术文档 | Document

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

开源项目 | Project

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

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

该框架可以在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

这个项目分为两个部分:

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

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

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

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

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

主程序配置集成 | Settings

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

引入框架依赖 | Framework

引入框架依赖:

<dependency>
            <groupId>com.gitee.starblues</groupId>
            <artifactId>spring-brick</artifactId>
            <version>3.1.0</version>
 </dependency>

具体主程序的pom文件配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
    <parent>
        <groupId>com.linghu</groupId>
        <artifactId>springboot-plugin-framework-example-linghu</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>example-main</artifactId>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.gitee.starblues</groupId>
            <artifactId>spring-brick</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
在配置文件加入配置 | Yaml

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

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

需要注意的是上面的 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
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);
    }
}

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

插件配置集成 | Settings

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

引入依赖 | XML
<!-- 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>

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

<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
    <parent>
        <groupId>com.linghu</groupId>
        <artifactId>springboot-plugin-framework-example-linghu</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>example-plugins-basic</artifactId>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!--        =====================插件配置集成========================-->
        <!-- spring-boot-starter依赖 -->
        <!--建议将spring-boot-starter依赖放到第一个位置, 以防止出现依赖冲突导致无法启动插件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.7.9</version>
        </dependency>
        <!--解决方案: 确保插件不包含spring-boot-starter-web依赖,而是让主程序来加载这个依赖。这样,主程序就可以管理所有的Spring Boot web依赖,避免了重复。
           如果您使用的是Maven,您可以在插件的pom.xml文件中移除对spring-boot-starter-web的依赖,或者如果您在主程序的pom.xml中已经定义了这个依赖,
           您可以在插件的pom.xml中添加<exclusions>元素来排除这个依赖。-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- spring-brick-bootstrap依赖 -->
        <dependency>
            <groupId>com.gitee.starblues</groupId>
            <artifactId>spring-brick-bootstrap</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- 主程序依赖 -->
        <!-- 将主程序以 provided 方式依赖到插件中 -->
        <dependency>
            <groupId>com.linghu</groupId>
            <artifactId>example-main</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
<!--    =================插件打包的配置===================-->
    <build>
        <plugins>
            <plugin>
                <groupId>com.gitee.starblues</groupId>
                <artifactId>spring-brick-maven-packager</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <!--当前打包模式为: 开发模式-->
                    <mode>dev</mode>
                    <!--插件信息定义-->
                    <pluginInfo>
                        <!--插件id-->
                        <id>example-plugins-basic</id>
                        <!--插件入口类, 定义说明见: 定义插件入口类-->
                        <bootstrapClass>com.linghu.controller.ExamplePlugin</bootstrapClass>
                        <!--插件版本号-->
                        <version>1.0.0-SNAPSHOT</version>
                    </pluginInfo>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
定义插件引导类 | 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);
    }
}

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

配置Maven打包插件 | Maven

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

<!--    =================插件打包的配置===================-->
    <build>
        <plugins>
            <plugin>
                <groupId>com.gitee.starblues</groupId>
                <artifactId>spring-brick-maven-packager</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <!--当前打包模式为: 开发模式-->
                    <mode>dev</mode>
                    <!--插件信息定义-->
                    <pluginInfo>
                        <!--插件id-->
                        <id>example-plugins-basic</id>
                        <!--插件入口类, 定义说明见: 定义插件入口类-->
                        <bootstrapClass>com.linghu.controller.ExamplePlugin</bootstrapClass>
                        <!--插件版本号-->
                        <version>1.0.0-SNAPSHOT</version>
                    </pluginInfo>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

新增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";
    }
}

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

编译打包插件 | JAR

这里打包有两种方法:

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

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

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

启动测试 | Main

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

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

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

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

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

Demo案例Git地址 | Gitee

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

完整项目demo:

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

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

mvn clean package进行编译~

目录
相关文章
|
4天前
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
18 6
|
10天前
|
Java 应用服务中间件 API
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
29 5
|
10天前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
27 2
|
14天前
|
开发框架 运维 监控
Spring Boot中的日志框架选择
在Spring Boot开发中,日志管理至关重要。常见的日志框架有Logback、Log4j2、Java Util Logging和Slf4j。选择合适的日志框架需考虑性能、灵活性、社区支持及集成配置。本文以Logback为例,演示了如何记录不同级别的日志消息,并强调合理配置日志框架对提升系统可靠性和开发效率的重要性。
|
13天前
|
人工智能 Java API
阿里云工程师跟通义灵码结伴编程, 用Spring AI Alibaba来开发 AI 答疑助手
本次分享的主题是阿里云工程师跟通义灵码结伴编程, 用Spring AI Alibaba来开发 AI 答疑助手,由阿里云两位工程师分享。
阿里云工程师跟通义灵码结伴编程, 用Spring AI Alibaba来开发 AI 答疑助手
|
1月前
|
人工智能 前端开发 Java
Spring AI Alibaba + 通义千问,开发AI应用如此简单!!!
本文介绍了如何使用Spring AI Alibaba开发一个简单的AI对话应用。通过引入`spring-ai-alibaba-starter`依赖和配置API密钥,结合Spring Boot项目,只需几行代码即可实现与AI模型的交互。具体步骤包括创建Spring Boot项目、编写Controller处理对话请求以及前端页面展示对话内容。此外,文章还介绍了如何通过添加对话记忆功能,使AI能够理解上下文并进行连贯对话。最后,总结了Spring AI为Java开发者带来的便利,简化了AI应用的开发流程。
419 0
|
1月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
22天前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
1月前
|
Java 开发者 Spring
理解和解决Spring框架中的事务自调用问题
事务自调用问题是由于 Spring AOP 代理机制引起的,当方法在同一个类内部自调用时,事务注解将失效。通过使用代理对象调用、将事务逻辑分离到不同类中或使用 AspectJ 模式,可以有效解决这一问题。理解和解决这一问题,对于保证 Spring 应用中的事务管理正确性至关重要。掌握这些技巧,可以提高开发效率和代码的健壮性。
91 13
|
机器学习/深度学习 Java 程序员
SpringBoot开发秘籍 - 利用 AOP 记录日志
Aspect Oriented Programming 面向切面编程。解耦是程序员编码开发过程中一直追求的。AOP也是为了解耦所诞生。
180 0
SpringBoot开发秘籍 - 利用 AOP 记录日志