PF4J是一个Java轻量级的插件框架,可以实现动态加载,执行,卸载外部插件(支持jar以及zip),具体可以看官网:https://pf4j.org/

本文例子基于Github地址:https://github.com/pf4j/pf4j

<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j</artifactId>
<version>3.0.1</version>
</dependency>

插件项目会涉及到3个工程:工程结构

  • plugin-api:定义可扩展接口
  • plugins:插件项目,可以包含多个插件,需要实现plugin-api中定义的接口
  • plugin-app:主程序,需要依赖plugin-api,加载并执行plugins

定义可扩展接口(plugin-api)

简单定义一个接口,需继承ExtensionPoint

package plugin.api;

import org.pf4j.ExtensionPoint;

public interface Greeting extends ExtensionPoint {

String getGreeting();
}

实现插件(plugins)

插件需要实现plugin-api定义的接口,并且使用@Extension标记:

package plugins;

import org.pf4j.Extension;
import plugin.api.Greeting;

@Extension
public class WelcomeGreeting implements Greeting {

public String getGreeting() {
return "Welcome";
}
}

插件打包(plugins)

插件打包时,需要往MANIFEST.MF写入插件信息,此处使用maven插件(打包命令为package):

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>welcome-plugin</Plugin-Id>
<Plugin-Version>0.0.1</Plugin-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>

根据Github上介绍,MANIFEST.MFPlugin-Id以及Plugin-Version是必须信息:

In above manifest I described a plugin with id welcome-plugin (mandatory attribute), with class org.pf4j.demo.welcome.WelcomePlugin (optional attribute), with version 0.0.1 (mandatory attribute) and with dependencies to plugins x, y, z (optional attribute).

此处定义插件ID为welcome-plugin,版本为0.0.1

加载执行插件(plugin-app)

package plugin.app;

import java.nio.file.Paths;
import java.util.List;

import org.pf4j.JarPluginManager;
import org.pf4j.PluginManager;

import plugin.api.Greeting;

public class Main {

public static void main(String[] args) {
// jar插件管理器
PluginManager pluginManager = new JarPluginManager();

// 加载指定路径插件
pluginManager.loadPlugin(Paths.get("plugins-0.0.1-SNAPSHOT.jar"));

// 启动指定插件(也可以加载所有插件)
pluginManager.startPlugin("welcome-plugin");

// 执行插件
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
for (Greeting greeting : greetings) {
System.out.println(">>> " + greeting.getGreeting());
}

// 停止并卸载指定插件
pluginManager.stopPlugin("welcome-plugin");
pluginManager.unloadPlugin("welcome-plugin");

}
}

运行输出:

>>> Welcome

其他

插件周期

如果对插件生命周期(如加载,执行,停止等)有兴趣的话,可以实现插件类继承Plugin

package plugins;

import org.pf4j.Plugin;
import org.pf4j.PluginWrapper;

public class WelcomePlugin extends Plugin {

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

@Override
public void start() {
System.out.println("WelcomePlugin.start()");
}

@Override
public void stop() {
System.out.println("WelcomePlugin.stop()");
}

@Override
public void delete() {
System.out.println("WelcomePlugin.delete()");
}
}

同时往MANIFEST.MF写入插件信息:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>welcome-plugin</Plugin-Id>
<Plugin-Version>0.0.1</Plugin-Version>
<!-- 新增 -->
<Plugin-Class>plugins.WelcomePlugin</Plugin-Class>
</manifestEntries>
</archive>
</configuration>
</plugin>

打包后运行输出:

WelcomePlugin.start()
>>> Welcome
WelcomePlugin.stop()

如果对运行流程感兴趣,或者调试,可以将日志级别设为debug日志

 log4j.properties示例:

log4j.rootLogger = debug,stdout,log

log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d [%-5p] %l %r ms: %m%n

log4j.appender.log = org.apache.log4j.DailyRollingFileAppender
log4j.appender.log.DatePattern = _yyyy-MM-dd
log4j.appender.log.File = logs/debug.log
log4j.appender.log.Encoding = UTF-8
log4j.appender.log.layout = org.apache.log4j.PatternLayout
log4j.appender.log.layout.ConversionPattern = %d [%-5p] (%c.%t): %m%n

PF4J使用的更多相关文章

  1. pf4j实例 插件框架

    实现整个过程需要三个部分,第一就是根接口,第二是插件,第三是应用程序.这是3个java项目. 首先要下载jar包,百度搜索maven repository,然后搜索pf4j,如下图,下载第一个的相应版 ...

  2. pf4j及pf4j-spring

    什么是PF4J 一个插件框架,用于实现插件的动态加载,支持的插件格式(zip.jar). 核心组件 Plugin:是所有插件类型的基类.每个插件都被加载到一个单独的类加载器中以避免冲突. Plugin ...

  3. Gitblit-Git版本服务器环境部署

    Gitblit介绍 Gitblit 是一个纯 Java 库用来管理.查看和处理 Git 资料库.相当于 Git 的 Java 管理工具,支持linux系统. Git是分布式版本控制系统,它强调速度.数 ...

  4. mac osx App store 安装软件 发生错误

    app store 安装软件时发生错误 解决办法: 1. 进入如下目录: sh-3.2# cd Library/Application\ Support/App\ Store/ sh-3.2# pwd ...

  5. 【原创】插件式ICE服务框架

    Zero ICE在跨平台.跨语言的环境中是一种非常好的RPC方案,而且使用简单.早期在使用ICE时,每一个后端功能模块都以独立服务方式部署,在功能模块较少时不会有明显的问题,但是随着功能模块的增多,部 ...

  6. iot平台异构对接文档

    iot平台异构对接文档 准备工作 平台提供的XAgent开发指南.pdf demo程序xagent-ptp-demo 平台上添加产品得到产品id和key 部署时需要插件的基础程序<xlink-x ...

  7. 透过现象看本质:Java类动态加载和热替换

    摘要:本文主要介绍类加载器.自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换. 最近,遇到了两个和Java类的加载和卸载相关的问题: 1) 是一道关于Java的判断题:一个类被首次 ...

  8. 服务器程序动态加载自定义jar包的过程

    需求: 用过hive的都知道,可以自定义hive的一个udf jar,然后将这个jar add到hive服务端,就会加载这个jar实现用户自定义逻辑.现在的需求就是实现这么一个服务端所做的事情! 场景 ...

随机推荐

  1. mybatis 字段类型映射一览表

  2. javascript 书

    作者limu 整理的书 http://web.jobbole.com/8087/ 慢慢整理, 后续还会添加

  3. Solution -「FJWC 2020」人生

    \(\mathcal{Description}\)   OurOJ.   有 \(n\) 个结点,一些结点有染有黑色或白色,其余待染色.将 \(n\) 个结点染上颜色并连接有向边,求有多少个不同(结点 ...

  4. 通过修改注册表将右alt键映射为application键

    通过修改注册表将右alt键映射为application键的方法有许多键盘没有APPLICATION(上下文菜单)键,本文将教您如何把右ALT键映射为apps键.1.映射请将以下注册表信息用记事本保存为 ...

  5. shell脚本部署redis以及redis主从复制和redis-cluster集群

    # 关于脚本: # 使用root用户执行此脚本,提前关闭selinux: # 执行脚本之前,hostsIP内的IP修改成自己的机器IP: # hostsIp内的IP数量如果有增加或者减少,for循环的 ...

  6. 树莓派GPIO开发(二)RGB模块-PWM调节

    配置环境 系统:Raspbian11(官方64位) 设备:树莓派CM4 一.PWM简单介绍 全称:Pulse-width modulation,脉冲宽度调制,简单的数模转换方法 1.基本原理 脉冲宽度 ...

  7. Spring Boot Starter 理解

    个人理解 快速集成,快速基础配置. 参考 深入springboot原理--一步步分析springboot启动机制(starter机制) 深入springboot原理--动手封装一个starter

  8. 搭建sock5代理

    安装 下载脚本 wget --no-check-certificate https://raw.github.com/Lozy/danted/master/install.sh -O install. ...

  9. volatile关键字的相关学习记录

    1:volatile是什么? Volatile是java虚拟机提供的一种轻量级的同步机制,具有 三大特性,分别是:保证可见性.不保证原子性.禁止指令重排 可见性: 概念:每一个线程都有自己的工作内存, ...

  10. msf常见命令

    msf命令全集 一.msfconsole ?   帮助菜单 back 从当前环境返回 banner   显示一个MSF banner cd   切换目录 color   颜色转换 connect   ...