同步操作将从 StarBlues/spring-brick 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
该框架主要是集成于springboot项目,用于开发插件式应用的集成框架。
https://mvnrepository.com/artifact/com.gitee.starblues/springboot-plugin-framework
Maven目录结构下所示
-example
- example-runner
- pom.xml
- example-main
- pom.xml
- example-plugin-parent
- pom.xml
- plugins
- example-plugin1
- pom.xml
- plugin.properties
- example-plugin2
- pom.xml
- plugin.properties
- pom.xml
- pom.xml
结构说明:
主程序为上述目录结构中的 example-main 模块。
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>springboot-plugin-framework</artifactId>
<version>${springboot-plugin-framework.version}</version>
</dependency>
最新版本:
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>springboot-plugin-framework</artifactId>
<version>2.1.3-RELEASE</version>
</dependency>
实现 com.plugin.development.integration.IntegrationConfiguration 接口。
import com.gitee.starblues.integration.DefaultIntegrationConfiguration;
import org.pf4j.RuntimeMode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "plugin")
public class PluginConfiguration extends DefaultIntegrationConfiguration {
/**
* 运行模式
* 开发环境: development、dev
* 生产/部署 环境: deployment、prod
*/
@Value("${runMode:dev}")
private String runMode;
/**
* 插件的路径
*/
@Value("${pluginPath:plugins}")
private String pluginPath;
/**
* 插件文件的路径
*/
@Value("${pluginConfigFilePath:pluginConfigs}")
private String pluginConfigFilePath;
@Override
public RuntimeMode environment() {
return RuntimeMode.byName(runMode);
}
@Override
public String pluginPath() {
return pluginPath;
}
@Override
public String pluginConfigFilePath() {
return pluginConfigFilePath;
}
/**
* 重写上传插件包的临时存储路径。只适用于生产环境
* @return String
*/
@Override
public String uploadTempPath() {
return "temp";
}
/**
* 重写插件备份路径。只适用于生产环境
* @return String
*/
@Override
public String backupPath() {
return "backupPlugin";
}
/**
* 重写插件RestController请求的路径前缀
* @return String
*/
@Override
public String pluginRestControllerPathPrefix() {
return "/api/plugins";
}
/**
* 重写是否启用插件id作为RestController请求的路径前缀。
* 启动则插件id会作为二级路径前缀。即: /api/plugins/pluginId/**
* @return String
*/
@Override
public boolean enablePluginIdRestControllerPathPrefix() {
return true;
}
public String getRunMode() {
return runMode;
}
public void setRunMode(String runMode) {
this.runMode = runMode;
}
public String getPluginPath() {
return pluginPath;
}
public void setPluginPath(String pluginPath) {
this.pluginPath = pluginPath;
}
public String getPluginConfigFilePath() {
return pluginConfigFilePath;
}
public void setPluginConfigFilePath(String pluginConfigFilePath) {
this.pluginConfigFilePath = pluginConfigFilePath;
}
@Override
public String toString() {
return "PluginArgConfiguration{" +
"runMode='" + runMode + '\'' +
", pluginPath='" + pluginPath + '\'' +
", pluginConfigFilePath='" + pluginConfigFilePath + '\'' +
'}';
}
}
配置说明:
runMode:运行项目时的模式。分为开发环境(dev)、生产环境(prod)
pluginPath: 插件的路径。开发环境建议直接配置为插件模块的父级目录。例如: plugins。如果启动主程序时, 插件为加载, 请检查该配置是否正确。
pluginConfigFilePath: 在生产环境下, 插件的配置文件路径。在生产环境下, 请将所有插件使用到的配置文件统一放到该路径下管理。如果启动主程序时, 报插件的配置文件加载错误, 有可能是该该配置不合适导致的。
uploadTempPath: 上传插件包时使用。上传插件包存储的临时路径。默认 temp(相对于主程序jar路径)
backupPath: 备份插件包时使用。备份插件包的路径。默认: backupPlugin(相对于主程序jar路径)
pluginRestControllerPathPrefix: 插件RestController请求的路径前缀
enablePluginIdRestControllerPathPrefix: 是否启用插件id作为RestController请求的路径前缀。启动则插件id会作为二级路径前缀。即: /api/plugins/pluginId/**
import com.gitee.starblues.integration.*;
import com.gitee.starblues.integration.initialize.AutoPluginInitializer;
import com.gitee.starblues.integration.initialize.PluginInitializer;
import org.pf4j.PluginException;
import org.pf4j.PluginManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class PluginBeanConfig {
/**
* 通过默认的集成工厂返回 PluginManager
* @param integrationConfiguration 集成的配置文件
* @return
* @throws PluginException
*/
@Bean
public PluginManager pluginManager(IntegrationConfiguration integrationConfiguration) throws PluginException {
IntegrationFactory integrationFactory = new DefaultIntegrationFactory();
return integrationFactory.getPluginManager(integrationConfiguration);
}
/**
* 定义默认的插件应用。使用可以注入它操作插件。
* @return
*/
@Bean
public PluginApplication pluginApplication(){
return new DefaultPluginApplication();
}
/**
* 初始化插件。此处定义可以在系统启动时自动加载插件。
* 如果想手动加载插件, 则可以使用 com.plugin.development.integration.initialize.ManualPluginInitializer 来初始化插件。
* @param pluginApplication
* @return
*/
@Bean
public PluginInitializer pluginInitializer(PluginApplication pluginApplication){
AutoPluginInitializer autoPluginInitializer = new AutoPluginInitializer(pluginApplication);
return autoPluginInitializer;
}
}
以 <scope>provided</scope>
方式引入springboot-plugin-framework包
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>springboot-plugin-framework</artifactId>
<version>${springboot-plugin-framework.version}</version>
<scope>provided</scope>
</dependency>
定义打包配置.主要用途是将 Plugin-Id、Plugin-Version、Plugin-Provider、Plugin-Class、Plugin-Dependencies
的配置值定义到META-INF\MANIFEST.MF
文件中
<properties>
<plugin.id>example-plugin1</plugin.id>
<plugin.class>com.plugin.example.plugin1.DefinePlugin</plugin.class>
<plugin.version>${project.version}</plugin.version>
<plugin.provider>StarBlues</plugin.provider>
<plugin.dependencies></plugin.dependencies>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
<maven-assembly-plugin.version>3.1.1</maven-assembly-plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>${maven-assembly-plugin.version}</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Plugin-Id>${plugin.id}</Plugin-Id>
<Plugin-Version>${plugin.version}</Plugin-Version>
<Plugin-Provider>${plugin.provider}</Plugin-Provider>
<Plugin-Class>${plugin.class}</Plugin-Class>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
manifestEntries
属性一致):plugin.id=example-plugin1
plugin.class=com.plugin.example.plugin1.DefinePlugin
plugin.version=2.0-SNAPSHOT
plugin.provider=StarBlues
配置说明:
plugin.id: 插件id
plugin.class: 插件实现类。见步骤3说明
plugin.version: 插件版本
plugin.provider: 插件作者
com.gitee.starblues.realize.BasePlugin
包import com.gitee.starblues.realize.BasePlugin;
import org.pf4j.PluginException;
import org.pf4j.PluginWrapper;
public class DefinePlugin extends BasePlugin {
public DefinePlugin(PluginWrapper wrapper) {
super(wrapper);
}
@Override
protected void startEvent() throws PluginException {
}
@Override
protected void deleteEvent() throws PluginException {
}
@Override
protected void stopEvent() {
}
}
并且将该类的包路径(com.plugin.example.plugin1.DefinePlugin)配置在步骤1和2的plugin.class属性中。
此步骤主要验证环境是否加载插件成功。
@RestController
@RequestMapping(path = "plugin1")
public class HelloPlugin1 {
@GetMapping()
public String getConfig(){
return "hello plugin1 example";
}
}
<scope>provided</scope>
方式引入到 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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.gitee.starblues</groupId>
<artifactId>plugin-example-runner</artifactId>
<version>2.0-RELEASE</version>
<packaging>pom</packaging>
<properties>
<gson.version>2.8.2</gson.version>
</properties>
<dependencies>
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>plugin-example-start</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 此处依赖用于解决在开发环境下, 插件包找不到对应依赖包 -->
<!--
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
<scope>provided</scope>
</dependency>
-->
</dependencies>
</project>
Working directory : D:\xx\xx\plugin-example
Use classpath of module: plugin-exampe-runner
勾选: Include dependencies with "Provided" scope
观察日志出现如下说明加载插件成功。
Plugin 'example-plugin1@2.0-RELEASE' resolved
Start plugin 'example-plugin1@2.0-RELEASE'
Init Plugins <example-plugin1> Success
浏览器输入:http://ip:port/api/plugins/example-plugin1/plugin1
响应并显示: hello plugin1 example
说明集成成功!
name: plugin1
plugin: examplePlugin1
setString:
- set1
- set2
listInteger:
- 1
- 2
- 3
subConfig:
subName: subConfigName
import com.gitee.starblues.annotation.ConfigDefinition;
import java.util.List;
import java.util.Set;
@ConfigDefinition("plugin1.yml")
public class PluginConfig1 {
private String name;
private String plugin;
private Set<String> setString;
private List<Integer> listInteger;
private String defaultValue = "defaultValue";
private SubConfig subConfig;
// 自行提供get set 方法
}
public class SubConfig {
private String subName;
public String getSubName() {
return subName;
}
// 自行提供get set 方法
}
该bean必须加上 @ConfigDefinition("plugin1.yml") 注解。其中值为插件文件的名称。
例如:
@Component("plugin2HelloService")
public class HelloService {
private final PluginConfig1 pluginConfig1;
private final Service2 service2;
@Autowired
public HelloService(PluginConfig1 pluginConfig1, Service2 service2) {
this.pluginConfig1 = pluginConfig1;
this.service2 = service2;
}
public PluginConfig1 getPluginConfig1(){
return pluginConfig1;
}
public String sayService2(){
return service2.getName();
}
}
在开发环境:配置文件必须放在resources目录下。并且@ConfigDefinition("plugin1.yml")中定义的文件名和resources下配置的文件名一致。
*在生产环境: 该文件存放在pluginConfigFilePath
配置的目录下。生产环境下插件的配置文件必须外置, 不能使用jar包里面的配置文件 *
插件之间的数据交互功能, 是在同一JVM运行环境下, 基于代理、反射机制完成方法调用。使用说明如下:
@Supplier("SupplierService")
public class SupplierService {
public Integer add(Integer a1, Integer a2){
return a1 + a2;
}
}
@Caller("SupplierService")
public interface CallerService {
Integer add(Integer a1, Integer a2);
}
3.被调用者和调用者也可以使用注解定义被调用的方法。例如:
被调用者:
@Supplier("SupplierService")
public class SupplierService {
@Supplier.Method("call")
public String call(CallerInfo callerInfo, String key){
System.out.println(callerInfo);
return key;
}
}
调用者:
@Caller("SupplierService")
public interface CallerService {
@Caller.Method("call")
String test(CallerInfo callerInfo, String key);
}
该场景主要用于参数类型不在同一个地方定义时使用。比如 被调用者的参数类: CallerInfo 定义在被调用者的插件中, 调用者的参数类: CallerInfo 定义在调用者的插件中。就必须配合 @Supplier.Method("")、@Caller.Method("") 注解使用, 否则会导致NotFoundClass 异常。
如果调用者没有使用注解 @Caller.Method("") 则默认使用方法和参数类型来调用。
4.对于3步骤中问题的建议
可以将被调用者和调用者的公用参数和返回值定义在主程序中、或者单独提出一个api maven包, 然后两者都依赖该包。
5.案例位置
basic-example:
com.basic.example.plugin1.service.SupplierService com.basic.example.plugin2.service.CallerService com.basic.example.plugin2.rest.ProxyController
文档见: springboot-plugin-framework-extension-mybatis
basic-example:插件基础功能案例。
integration-mybatis: 针对Mybatis集成的案例。
integration-mybatisplus: 针对Mybatis-Plus集成的案例
普通例子运行见:basic-example
windows环境下运行: package.bat
linux、mac 环境下运行: package.sh
接口地址查看: http://127.0.0.1:8080/doc.html
例子见:integration-mybatis
windows环境下运行: package.bat
linux、mac 环境下运行: package.sh
sql在 integration-mybatis/sql 文件夹下。
接口地址查看: http://127.0.0.1:8081/doc.html
例子见:integration-mybatisplus
windows环境下运行: package.bat
linux、mac 环境下运行: package.sh
sql在 integration-mybatisplus/sql 文件夹下。
接口地址查看: http://127.0.0.1:8082/doc.html
-main.jar
-main.yml
-plugins
-plugin1.jar
-plugin2.jar
-pluginFile
-plugin1.yml
-plugin2.yml
1.在插件目录下新建 enabled.txt
文件
2.enabled.txt的内容为:
########################################
# - 启用的插件
########################################
example-plugin1
将需要启用的插件id配置到文件中。
所有注释行(以#字符开头的行)都将被忽略。
1.在插件目录下新建 disabled.txt
文件
2.disabled.txt的内容为:
########################################
# - 禁用的插件
########################################
example-plugin1
将需要启用的插件id配置到文件中。
所有注释行(以#字符开头的行)都将被忽略。
如果 pluginPath 配置为相当路径,请检查是否是相对于当前工作环境的目录。
如果 pluginPath 配置为绝对路径,请检查路径是否正确。
<dependency>
<groupId>com.gitee.starblues</groupId>
<artifactId>springboot-plugin-framework</artifactId>
<version>${springboot-plugin-framework.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
</exclusions>
</dependency>
启动配置: 在Before launch 下-> 点击小+号 -> Build ->Artifacts -> 选择上一步新增的>Artifacts
859570617
在PluginUser接口新增getMainBeans方法, 用于获取Spring管理的主程序接口的实现类。
使用场景: 在主程序中定义了接口, 插件中存在实现了该接口的实现类, 通过PluginUser 的 getPluginBeans(接口Class) 可以获取所有插件中实现该接口的实现类。具体详见源码。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。