为了方便框架主版本的升级和系统的解耦抽象,现基于SpringBrick进行插件化开发。
# 准备工作
- 确认主框架
JeecgBoot
框架版本,目前3.7.0
版本经测试可以正常运行,推测SpringBoot2.X
的版本均可支持。 SpringBrick
使用版本为3.1.2
。- JDK版本为
1.8
。
# 确定主程序及主包
按照JeecgBoot
的代码架构设计,以单体为例,主程序定为jeecg-module-system
下的jeecg-system-start
。故,主包即为org.jeecg
。因此,插件包名应为其他名称,或者为org.jeecg.xxx
。
# jeecg-system-start
的pom.xml
添加spring-brick
依赖。
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>spring-brick</artifactId>
<version>${spring-brick.version}</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>com.gitee.starblues</groupId>
<artifactId>spring-brick-maven-packager</artifactId>
<configuration>
<mode>main</mode>
<mainConfig>
<mainClass>org.jeecg.JeecgSystemApplication</mainClass>
<packageType>jar</packageType>
</mainConfig>
<includeSystemScope>false</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
# jeecg-system-start
的application.yaml
添加spring-brick
配置项。
plugin:
runMode: dev
# 主包路径,和上面的对应
mainPackage: org.jeecg
pluginPath:
# 示例插件路径
- ~/jeecg-plugins
# 修改jeecg-system-start
的JeecgSystemApplication.java
启动文件。
// 原代码
package org.jeecg;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 单体启动类
* 报错提醒: 未集成mongo报错,可以打开启动类上面的注释 exclude={MongoAutoConfiguration.class}
*/
@Slf4j
@SpringBootApplication
public class JeecgSystemApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(JeecgSystemApplication.class);
}
public static void main(String[] args) throws UnknownHostException {
ConfigurableApplicationContext application = SpringApplication.run(JeecgSystemApplication.class, args);
Environment env = application.getEnvironment();
String ip = InetAddress.getLocalHost().getHostAddress();
String port = env.getProperty("server.port");
String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path"));
log.info("\n----------------------------------------------------------\n\t" +
"Application Jeecg-Boot is running! Access URLs:\n\t" +
"Local: \t\thttp://localhost:" + port + path + "/\n\t" +
"External: \thttp://" + ip + ":" + port + path + "/\n\t" +
"Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
"----------------------------------------------------------");
}
}
// 修改后
package org.jeecg;
import com.gitee.starblues.loader.launcher.SpringBootstrap;
import com.gitee.starblues.loader.launcher.SpringMainBootstrap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.net.UnknownHostException;
/**
* 单体启动类
* 报错提醒: 未集成mongo报错,可以打开启动类上面的注释 exclude={MongoAutoConfiguration.class}
*/
@Slf4j
@SpringBootApplication
public class JeecgSystemApplication implements SpringBootstrap {
public static void main(String[] args) throws UnknownHostException {
SpringMainBootstrap.launch(JeecgSystemApplication.class, args);
log.info("Application Jeecg-Boot is running!");
}
@Override
public void run(String[] args) {
SpringApplication.run(JeecgSystemApplication.class, args);
}
}
修改说明:
- 取消了对
SpringBootServletInitializer
的继承,并删除configure
方法,否则在maven package
时会报错。 - 添加了对
SpringBootstrap
的实现。 main
方法通过SpringMainBootstrap.launch
进行启动。- 重写了
run
方法。
# 主程序其他配置
- 鉴权处理,根据测试结果来看,插件中是不支持
@IgnoreAuth
注解的。所以插件中需要放权的请求要在ShiroConfig.java
进行处理。但是,如果每个插件需要放权都要在主程序配置,并重启一次,则失去了插件部分意义,故推荐添加配置filterChainDefinitionMap.put("/plugins/**/ignoreAuth/**", "anon");
。插件中,把需要放权的请求统一放在ignoreAuth
接口下。这样,就可以不再需要调整主程序的鉴权配置了。
# 插件开发
目录结构设计推荐(插件建立一个父模块进行管理,根据上面的配置,我们的父模块就是jeecg-plugins
):
-example
- example-main
- pom.xml
- plugins
- example-plugin1
- pom.xml
- example-plugin2
- pom.xml
- pom.xml
- pom.xml
插件父模块的pom.xml
配置如下:
<?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">
<parent>
<artifactId>jeecg-boot-parent</artifactId>
<groupId>org.jeecgframework.boot</groupId>
<version>3.7.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jeecg-plugins</artifactId>
<packaging>pom</packaging>
<!-- 两个子插件 -->
<modules>
<module>plugins-example-1</module>
<module>plugins-example-2</module>
</modules>
<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>
<!-- 插件统一SpringBoot依赖版本 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.18</version>
</dependency>
<!-- 加入对主程序的依赖,注意是provided范围 -->
<dependency>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-system-start</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<!-- 添加SpringBrick依赖,注意插件依赖的是spring-brick-bootstrap,和主程序的不一样 -->
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>spring-brick-bootstrap</artifactId>
<version>${spring-brick.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.gitee.starblues</groupId>
<artifactId>spring-brick-maven-packager</artifactId>
<version>${spring-brick.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
插件子模块的pom.xml
配置如下:
<?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">
<parent>
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-plugins</artifactId>
<version>3.7.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>plugins-example-1</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.gitee.starblues</groupId>
<artifactId>spring-brick-maven-packager</artifactId>
<configuration>
<!-- 可选项dev, prod -->
<mode>${plugin.build.mode}</mode>
<pluginInfo>
<id>plugins-example-1</id>
<!-- 启动文件完整包路径 -->
<bootstrapClass>org.jeecg.plugin.ExampleOneApplication</bootstrapClass>
<version>1.0.0</version>
<provider>Zoneber</provider>
<description>示例插件</description>
<!-- 配置文件,默认目录resource -->
<configFileName>example-config.yaml</configFileName>
</pluginInfo>
<prodConfig>
<packageType>jar</packageType>
</prodConfig>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
插件子模块启动文件内容:
package org.jeecg.plugin;
import com.gitee.starblues.bootstrap.SpringPluginBootstrap;
import com.gitee.starblues.bootstrap.annotation.OneselfConfig;
import org.jeecg.JeecgSystemApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@OneselfConfig(mainConfigFileName = {"application.yml", "application-dev.yml"})
@EnableConfigurationProperties
public class ExampleOneApplication extends SpringPluginBootstrap {
public static void main(String[] args) {
// 注意这里加载了主程序的启动类
new ExampleOneApplication().run(JeecgSystemApplication.class, args);
}
}
之后对子模块进行mvn clean package
,package
可能会报找不到符号
。这时需要对主模块进行build
(对主模块右键点击后选择build
处理,如果还是报错,则进行rebuild
处理)。提示成功后启动主模块,提示插件[xxx@1.0.0]加载成功
,即说明插件加载成功。
# 部署
生产环境推荐结构:
-main.jar
-application.yml
-plugins
-plugin1.jar
-plugin2.zip
-plugin3
生产环境application.yml
配置:
plugin:
runMode: prod
mainPackage: org.jeecg
# 如果配置是 windows 下路径, mac、linux 自行修改
pluginPath:
- /plugins
maven
选择prod
环境,然后进行package
。插件打包完成后,jar包名称默认为xxx-1.0.0-repackage.jar
。之后将主程序和插件分别上传,启动主程序,提示插件[xxx@1.0.0]加载成功
,即说明插件加载成功。部署全部完成!