使用PF4J实现插件化系统-入门

简介:

在进行业务平台型系统开发时,常常遇到接口大致相同,但是不同的业务的场景,其实现却有所不同。在分工方面,不同的业务场景,可能是不同的开发人员。这时就可以通过插件化的方式,针对不同的业务场景,实现不同的插件,来满足业务的需求。

PF4J是一个Java轻量级的插件框架,使用PF4J可以轻松的将一个Java应用转成一个插件化的应用。其拥有最小的依赖关系和很强的扩展性。

<dependency>
    <groupId>ro.fortsoft.pf4j</groupId>
    <artifactId>pf4j</artifactId>
    <version>${pf4j.version}</version>
</dependency>

目前pf4j的最新是1.3.0。以下示例我们都以这个版本为例。

工程结构

pf4j-plugin-demo

插件化的工程结构如上:

api:定义可扩展的接口,其他插件实现这里所定义的接口。在实际的工程中,定义可扩展点的接口是比较难的地方
app:运行程序,这里是程序的入口。插件直接拷贝至指定的目录,app就可以找到指定的插件
plugins:插件模块,这里实现api中所定义的接口。在实际的工程中,这部分可以是单独的代码库,其依赖api以及项目的一些基础模块
定义可扩展接口

我们先来定义api的接口

public interface Greeting extends ExtensionPoint {

    String message(String name);
}

这里我们定义了一个Greeting接口。

以上我们继承了ExtensionPoint接口,用于标记这个接口是提供一个扩展点。PF4J任何在接口和抽象类都可以继承它。

实现插件

接下来我们实现插件

public class ChinesePlugin extends Plugin {

    private static final Logger logger= LoggerFactory.getLogger(ChinesePlugin.class);

    public ChinesePlugin(PluginWrapper wrapper) {
        super(wrapper);
    }

    @Override
    public void start() throws PluginException {
        System.out.println("Chinese plugin start.");
        super.start();
    }

    @Override
    public void stop() throws PluginException {
        logger.info("Chinese plugin stop.");
        super.stop();
    }
}```
在实现插件时,首先我们继承Plugin类,实现其start和stop接口。在PluginManager加载完成之后,调用startPlugins就会执行这里的start方法。

@Extension
public class ChineseGreeting implements Greeting {

@Override
public String message(String name) {
    return "你好," + name;
}

}`
以上就实现了中文版的插件。

同样英文版插件如下:

public class EnglishPlugin extends Plugin {

    public EnglishPlugin(PluginWrapper wrapper) {
        super(wrapper);
    }

    @Override
    public void start() throws PluginException {
        System.out.println("English plugin start.");
        super.start();
    }

    @Override
    public void stop() throws PluginException {
        System.out.println("English plugin start.");
        super.stop();
    }
}
@Extension
public class EnglishGreeting implements Greeting {

    @Override
    public String message(String name) {
        return "Hi," + name;
    }
}```
插件打包

在插件编写完成之后,需要打包和进行版本管理。PF4j支持zip包的方式,在zip包中有classes和lib两个目录,classes中为插件的class文件,lib为插件依赖的第三方包。在maven中,我们可以使用maven-assembly插件,打出zip包。具体配置可下载demo代码查看。

插件加载、启动
public static void main(String[] args) {
    //使用默认的插件管理器
    PluginManager pluginManager = new DefaultPluginManager(new File("/app/plugins").toPath());

    //加载插件
    pluginManager.loadPlugins();

    //启动插件
    pluginManager.startPlugins();

    //获取所有的Greeting的扩展实现
    List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
    for (Greeting greeting : greetings) {
        System.out.println( greeting.message("yywang"));
    }
}```

在以上代码中,我们使用了DefaultPluginManager插件管理器,在实际使用中,也可以自己是插件管理器。在这里我们读取/app/plugins目录下的所有的插件。

第二步,加载插件。这里会把所有的插件的Class加载到PluginClassLoader中,为避免冲突,每个插件都有自己的PluginClassLoader。

第三步,启动插件。这里很简单就是把所有的插件调用start方法,启动插件,并且把插件的状态设置成STARTED

第四步,运行插件。这里我们通过获取所有Greeting的实现运行插件。pluginManager还有一些其他接口,满足我们不同的业务场景。

运行

对以上插件进行打包,并把插件拷贝至指定的目录,运行以上main方法,结果如下

>>> 你好,yywang
>>> Hi,yywang```
以上就是一个关于PF4J的入门,后面我们还会深入了解,如何定义插件管理、插件版本管理、插件生命周期、开发模式和线上模式等等。

目录
相关文章
|
8月前
|
JSON 机器人 Linux
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
推荐一款嵌入式Linux开源框架与封装-cpp-tbox
156 3
|
5月前
|
监控 安全 网络安全
SOC:简介、功能及其优点
【8月更文挑战第19天】
298 0
|
7月前
|
监控 Dubbo Java
深入理解Java SPI:服务发现与扩展的利器(一)
深入理解Java SPI:服务发现与扩展的利器(一)
|
Linux 开发工具 芯片
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(二十八)驱动设计的思想:面向对象/分层/分离
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(二十八)驱动设计的思想:面向对象/分层/分离
172 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(二十八)驱动设计的思想:面向对象/分层/分离
|
存储 Java 开发者
RISC-V生态全景解析(十五):YoC组件介绍系列五: KV组件
芯片开放社区(OCC)面向开发者推出RISC-V系列内容,通过多角度、全方位解读RISC-V,系统性梳理总结相关理论知识,构建RISC-V知识图谱,促进开发者对RISC-V生态全貌的了解。
468 0
RISC-V生态全景解析(十五):YoC组件介绍系列五: KV组件
|
存储 缓存 安全
RISC-V生态全景解析(十四):YoC组件介绍系列四: PARTITION组件
芯片开放社区(OCC)面向开发者推出RISC-V系列内容,通过多角度、全方位解读RISC-V,系统性梳理总结相关理论知识,构建RISC-V知识图谱,促进开发者对RISC-V生态全貌的了解。
440 0
RISC-V生态全景解析(十四):YoC组件介绍系列四: PARTITION组件
|
编译器 C语言
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV
216 0
QT应用编程: QtCreate编译部署开源音视频框架模块QtAV
|
IDE 开发工具
RISC-V MCU开发 (十一):跨内核工程转换
大多数嵌入式工程师使用Keil进行开发,但Keil目前不支持RISC-V内核,只支持ARM内核。MounRiver® Studio(MRS)同时支持两种内核,为了方便工程师从ARM内核迁移至RISC-V内核,MRS增加了Keil工程转换的功能。
RISC-V MCU开发 (十一):跨内核工程转换
|
编解码 语音技术 uml
基于YoC的轻量级AV框架设计
简介 AV框架是一个轻量级的多媒体开发框架。其采用典型的4层多媒体模型设计及面向对象的思想开发,使得用户在此基础上易于复用与扩展。 当前AV组件中提供了wav、mp3、m4a、amrnb、amrwb、flac、adts等音频格式的支持。框架本身的设计向后提供视频支持。若有视频播放的需要,可基于此AV框架进行扩展。
基于YoC的轻量级AV框架设计
|
存储 调度
带你读《C/OS-III内核实现与应用开发实战指南:基于STM32》之三:任务的定义与任务切换
本书分为两部分,第一部分先教你如何从0到1把uC/OS-III内核写出来,从底层的汇编开始讲解任务如何定义、如何切换,还讲解了阻塞延时如何实现、如何支持多优先级、如何实现任务延时列表以及时间片等uC/OS的核心知识点;第二部分讲解uC/OS-III内核组件的应用以及使用uC/OS-III进行多任务编程。

热门文章

最新文章