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. gpg 使用入门

    1. 生成秘钥 gpg --full-generate-key 等价于 gpg --full-gen-key Real name: yellowconvict为该秘钥的名字,也称为 USER-ID 在 ...

  2. Byobu安装与使用

    机子为Ubuntu18 Byobu安装 sudo apt-get install byobu Byobu安装后默认禁用,需要启用Byobu,之后每次登陆自动启用Byobu byobu-enable 还 ...

  3. 使用污点分析检查log4j问题

    摘要:log4j问题的余波还在继续,为什么这个问题潜伏了这么长时间,大家一直没有发现?这里从静态分析的角度谈下log4j问题的发现. 本文分享自华为云社区<使用污点分析检查log4j问题> ...

  4. [源码解析] NVIDIA HugeCTR,GPU 版本参数服务器 --(1)

    [源码解析] NVIDIA HugeCTR,GPU版本参数服务器 --(1) 目录 [源码解析] NVIDIA HugeCTR,GPU版本参数服务器 --(1) 0x00 摘要 0x01 背景 1.1 ...

  5. MXNet源码分析 | Gluon接口分布式训练流程

    本文主要基于MXNet1.6.0版本,对Gluon接口的分布式训练过程进行简要分析. 众所周知,KVStore负责MXNet分布式训练过程中参数的同步,那么它究竟是如何应用在训练中的呢?下面我们将从G ...

  6. 聊聊几个阿里 P8、P9 程序员的故事

    大家好,我是对白. 阿里 P8 程序员年薪百万已经是公开的秘密了,有人关心他们年薪百万,而我更加关注阿里这些 P8.P9 程序员的成长故事,在聊这些大牛的故事之前,跟大家稍微简单聊下阿里技术人等级制度 ...

  7. BGP4协议测试——信而泰网络测试仪实操

    文章关键词 BGP:路由测试:协议测试:矢量路由协议: 一.前言: BGP是自治系统外部路由协议,用来在AS之间传递路由信息 路径矢量路由协议,从设计上避免了环路的发生 其路由信息中携带了所经过的全部 ...

  8. React函数类组件及其Hooks学习

    目录 函数类组件 函数式组件和类式组件的区别: 为什么要使用函数式组件? Hooks概念及常用的Hooks 1. useState: State的Hook 语法 useState()说明: setXx ...

  9. 浅谈bi工具的含义和不同类型

    ​什么是BI工具? 商业智能(BI)工具是利用一组方法和技术来准备,呈现和帮助分析数据的工具.通过此过程,数据将转化为可操作的业务信息,帮助决策者和最终用户做出更有效的数据驱动决策. 商业智能使用的一 ...

  10. 【C#基础概念】命名规范

    1. 引言 本文是一套面向C# programmer 和C# developer 进行开发所应遵循的开发规范. 按照此规范来开发C#程序可带来以下益处: ·         代码的编写保持一致性, · ...