插件框架PF4J-从理论到实践
PF4J:Plugin Framework for Java
目录
是什么?
不是什么?
特点
组件
主要类
流程概述
spring-pf4j
思考
功能模块化
我对pf4j的封装和使用demo
GitHub - chlInGithub/pf4jDemo: pf4j demo
是什么?
开源轻量级的插件框架。通过插件形式对系统功能进行个性化扩展。插件需要实现扩展点,扩展点由系统进行定义。
不是什么?
功能模块化加载框架。虽然介绍中描述pf4j可以将庞大的系统转化为模块系统,但依据我的实践来看,仅仅依赖pf4j只能动态加载扩展,无法动态加载完整的功能模块。
特点
- 开源轻量级的插件框架
- 简单的标记扩展点,使用interface ExtensionPoint即可将接口和抽象类定义为扩展点
- 简单的标记扩展,使用@Extension即可定义一个扩展
组件
插件 等同于 由 扩展点、扩展、生命周期行为 构成的一个集合。
| Plugin | 所有插件的基类。每一个插件均由单独的classloader进行加载,避免冲突。 |
| PluginManager | 对插件进行切面化管理,如loading, starting, stopping。已提供3中实现,JarPluginManager, ZipPluginManager, DefaultPluginManager(jar_zip)。也可自行实现个性化pluginManager,需要实现AbstractPluginManager。 |
| PluginLoader | 加载插件需要的所有信息,如class |
| ExtensionPoint | 扩展点 |
| Extension | 扩展,即扩展点的实现 |
主要类
| PluginManager | pf4j通过PluginManager向外提供plugin管理能力,如生命周期控制、获取扩展实例 |
| PluginWrapper | plugin的包装类 |
| ManifestPluginDescriptorFinder | 从(支持jar\zip\目录)manifest文件读取插件信息,如Plugin-Id(用于避免重复load)、Plugin-Version、Plugin-Class |
| PluginLoader | 用于load plugin需要的所有信息,每个pluginPath对应一个pluginLoader,为每个plugin提供独立的classloader。 如JarPluginLoader |
| PluginClassLoader | 自定义的classLoader,修改了loadClass的逻辑。每个plugin对应一个PluginClassLoader实例 |
| PluginState | 插件生命周期期间的各种状态 |
| DependencyResolver | 插件间依赖关系分解器。一系列插件之间构建依赖图,唯一入口resolve可以返回依赖分解结果,如插件之间是否存在循环依赖、能否找到依赖的插件、插件依赖版本是否正确等。 |
| LegacyExtensionFinder | 读取plugin包中META-INF/extensions.idx文件,获取扩展信息和实例。 |
生命周期概述
| 加载插件过程 | MF文件中插件描述-->插件独立classLoader-->插件间依赖解析-->插件已解析状态 |
| 开始插件过程 | 加载Plugin实现并生成实例-->调用Plugin.start()-->插件已开始状态 |
| 获取某个扩展点实现类的实例 | |
| 停止插件 | 插件状态变为停止 |
| 卸载插件 | 从集合中清除,关闭classLoader |
spring-pf4j
将扩展注册为spring ioc bean
思考
如何支持租户场景?
pf4j非线程安全,允许不同租户维护各自插件的场景,需要在pf4j基础上再包裹一层,一方面增加线程安全,一方面维护租户与插件、扩展的关系。
需要以一种路径规范存放插件jar,如下图:

如何支持插件依赖的jar?
- 方式1:系统列举出支持的jar集合,插件依赖其中的jar。在demo中已体现该场景,插件正常运行。
如图为插件的pom依赖,插件jar中不包含依赖的任何jars。

插件jar放到上图的租户路径下,在系统中运行Pf4jTest.main,插件扩展运行正常。因为系统的classpath中包含common-lang jar,所以classloader可以找到common-lang中class。
扩展运行结果如下,可以清晰看出,两个插件的classloader是独立的。

- 方式2:插件jar内部包含依赖的jars
- 方式2.1:jdk的classloader不支持嵌套jar,需参考spring LaunchedURLClassLoader或JarClassLoader(http://www.jdotsoft.com/JarClassLoader.php)。在不改变pf4j源码情况下,无法实现该方案,因为pf4j使用URLClassLoader。
- 方式2.2:解压插件jar-->pf4j加载插件jar-->修改生成的classloader的扫描范围,添加依赖jars路径-->启动插件jar
- 方式3:系统根据插件jar的(maven)依赖去下载依赖的jar
功能模块化
基本能力:系统功能进行模块划分,模块可动态加载和卸载,模块独立且隔离,模块间资源不产生冲突。
设计思路:独立的classloader(修改加载class的顺序,自有范围-->双亲委派)、springcontext、生命周期管理
相关文章:
插件框架PF4J-从理论到实践
PF4J:Plugin Framework for Java 目录 是什么? 不是什么? 特点 组件 主要类 流程概述 spring-pf4j 思考 功能模块化 我对pf4j的封装和使用demo GitHub - chlInGithub/pf4jDemo: pf4j demo 是什么? 开源轻量级的插件框架。通过插件…...
怎么将pdf文件免费转为扫描件
推荐两个工具,也算是给自己记一下 1、手机:扫描全能王APP 太好使了,可以直接拍照并转换为扫描件 不开会员的话会出现水印,因为我都是自己用或者交作业就没开 支持读取相册,一次一张、多张都可以 如果不想要水印也…...
vue+nodejs校园二手物品交易市场网站_xa1i4
。为满足如今日益复杂的管理需求,各类管理系统程序也在不断改进。本课题所设计的校园二手交易市场,使用vue框架,Mysql数据库、nodejs语言进行开发,它的优点代码不能从浏览器查看,保密性非常好,比其他的管理…...
Barra模型因子的构建及应用系列六之Book-to-Price因子
一、摘要 在前期的Barra模型系列文章中,我们构建了Size因子、Beta因子、Momentum因子、Residual Volatility因子和NonLinear Size因子,并分别创建了对应的单因子策略,其中Size因子和NonLinear Siz因子具有很强的收益能力。本节文章将在该系列…...
【c语言习题】使用链表解决约瑟夫问题
创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!! 主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步! 🔥c语言系列专栏:c语言之路重点知识整合 &#x…...
JVM之类的初始化与类加载机制
类的初始化 clinit 初始化阶段就是执行类构造器方法clinit的过程。此方法不需定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来。构造器方法中指令按语句在源文件中出现的顺序执行。clinit不同于类的构造器。(关联:…...
面试专题:java 多线程(1)----synchronized关键字相关问答
在java 多线程 面试中最多问题1.悲观锁和乐观锁;2.synchronized和lock的区别;3.可重入锁和非可重入锁的区别;4.多线程是解决什么问题的;5.线程池解决什么问题的;6.线程池原理;7.线程池使用注意事项…...
VMware SD-WAN 5.2 发布 - 软件定义的 WAN
VMware SD-WAN 5.2 发布 - 软件定义的 WAN SD-WAN 解决方案的领导者 请访问原文链接:https://sysin.org/blog/vmware-sd-wan-5/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org 产品概述 软件定义的 WAN (SD-WAN)…...
Oracle+11g+RAC+PSU_EAM(2)
2.15 解压安装介质 在获取开篇1.2节中提到的安装介质如下: [rootebsrac1 ~]# ls -l -rw-r–r– 1 root root 1358454646 Apr 20 16:22 p13390677_112040_Linux-x86-64_1of7.zip -rw-r–r– 1 root root 1142195302 Apr 20 16:29 p13390677_112040_Linux-x86-64_…...
智能出行 驱动未来|2023 开放原子全球开源峰会 CARSMOS 开源智能出行生态年会即将启幕
由开放原子开源基金会主办,元遨 / CARSMOS 开源智能出行项目组协办,深信科创、Futurewei Technologies、Open Motors、北极雄芯等单位共同承办的 2023 开放原子全球开源峰会 “CARSMOS 开源智能出行生态年会” 将于 6 月 12 日在北京经开区北人亦创国际会…...
Linux:centos:周期性计划任务管理《crontab》
crontab常用基础属性 -e 编辑计划任务 -l 查看计划任务 -r 删除计划任务 -u 指定用户的计划任务 首先创建一个名为test的用户名 crontab时间规定 格式:分钟 小时 日期 月份 星期 命令 分钟-- 0-59整数 小时 -- 0-23整数 日期 -- 1--31 整数 月份 -- 1-12 整数 星期…...
克拉默法则证明(Cramer‘s Rule)
若 n 个方程 n 个未知量构成的非齐次线性方程组: { a 11 x 1 a 12 x 2 . . . a 1 n x n b 1 a 21 x 1 a 22 x 2 . . . a 2 n x n b 2 . . . . . . a n 1 x 1 a n 2 x 2 . . . a n n x n b n \begin{equation*} \begin{cases} a_{11}x_{1} a_ {12}x_{2}…...
【接口防刷】处理方案
【接口防刷】 欢迎使用【接口防刷】常见的处理方案访问次数和频率限制验证码校验登录校验机制数据交互加密异常监测机制附录 欢迎使用【接口防刷】常见的处理方案 接口防刷处理方案是指为了防止恶意攻击或非法数据采集,采取一系列技术措施来保护接口数据的安全和完…...
安装Linux-SUSE操作系统
文章目录 一、安装Linux-SUSE系统1、环境准备2、SUSE 镜像的下载2.1、下载企业服务器2.2、ARM和桌面的ISO 3、安装SUSE4、配置本地 yum 源5、SUSE常用安装命令6、在 SUSE系统上安装mysql数据库步骤:7、破解SUSE系统root密码 一、安装Linux-SUSE系统 1、环境准备 操…...
二、机器人的结构设计
1 、螺丝连接的坚固性 坚固性是机器人能顺利完成指定任务的一个重要条件,无论我们程序设计的如何完美, 如果不能保证机器人具有坚固性和稳定性,就无法保证任务的顺利完成,机器人在运行时如 果发生散架和分裂都会影响其功能的实现…...
UITableView学习笔记
看TableView的资料其实已经蛮久了,一直想写点儿东西,却总是因为各种原因拖延,今天晚上有时间静下心来记录一些最近学习的TableView的知识。下面进入正题,UITableView堪称UIKit里面最复杂的一个控件了,使用起来不算难&a…...
Nginx反向代理与负载均衡
简介 Nginx 是一款高性能、轻量级的 Web 服务器软件,常用于反向代理和负载均衡。以下是 Nginx 反向代理和负载均衡的基本原理和实现方式 1、反向代理 当客户端请求访问一个 Web 服务器时,首先会发送请求到 Nginx,然后 Nginx 将请求转…...
Delaunay三角剖分学习笔记
文章目录 Delaunay三角剖分学习笔记1 Voronoi \text{Voronoi} Voronoi图1.1 定义与性质 2 三角剖分2.1 定义与性质2.2 质量(quality)评定标准 3 Delaunay三角剖分3.1 定义3.2 准则与性质 4 Delaunay三角剖分算法4.1 Bowyer-Watson算法4.1.1 算法步骤:4.1.2 算法伪代…...
@Resource和@Autowired的区别
1.相同点 Resource和Autowired这两个注解的作用都是在Spring生态里面去实现Bean的依赖注入 2.不同点 2.1 Autowired 首先,Autowired是Spring里面提供的一个注解,默认是根据类型来实现Bean的依赖注入。 Autowired注解里面有一个required属性默认值是t…...
linux达梦数据库的安装与卸载
一、安装 创建dmdba用户及用户组 创建安装目录: mkdir -p /dm8 创建组 :groupadd dinstall 创建用户 :useradd -g dinstall dmdba 设置密码 :passwd dmdba 创建文件夹:mkdir /dmdata 更改安装目录所有者: c…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
