Spring Boot集成pf4j实现插件开发功能

1.什么是pf4j?

一个插件框架,用于实现插件的动态加载,支持的插件格式(zip、jar)。

核心组件

  • Plugin:是所有插件类型的基类。每个插件都被加载到一个单独的类加载器中以避免冲突。

  • PluginManager:用于插件管理的所有方面(加载、启动、停止)。您可以使用内置实现作为JarPluginManager, ZipPluginManager, DefaultPluginManager(它是一个JarPluginManager+ ZipPluginManager),或者您可以从AbstractPluginManager(仅实现工厂方法)开始实现自定义插件管理器。

  • PluginLoader:加载插件所需的所有信息(类)。

  • ExtensionPoint:是应用程序中可以调用自定义代码的点。这是一个java接口标记。任何 java 接口或抽象类都可以标记为扩展点(实现ExtensionPoint接口)。

  • Extension:是扩展点的实现。它是一个类上的 Java 注释

场景

有一个spring-boot实现的web应用,在某一个业务功能上提供扩展点,用户可以基于SDK实现功能扩展,要求可以管理插件,并且能够在业务功能扩展点处动态加载功能。

2.代码工程

实验目的

实现插件动态加载,调用 卸载

Demo整体架构

  • pf4j-api:定义可扩展接口。

  • pf4j-plugins-01:插件项目,可以包含多个插件,需要实现 plugin-api 中定义的接口。所有的插件jar包,放到统一的文件夹中,方便管理,后续只需要加载文件目录路径即可启动插件。

  • pf4j-app:主程序,需要依赖 pf4j-api ,加载并执行 pf4j-plugins-01 

pf4j-api

导入依赖

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

自定义扩展接口,集成 ExtensionPoint ,标记为扩展点

package com.et.pf4j;
import org.pf4j.ExtensionPoint;
public interface Greeting extends ExtensionPoint {
String getGreeting();
}

打包给其他项目引用

pf4j-plugins-01

如果你想要能够控制插件的生命周期,你可以自定义类集成 plugin 重新里面的方法

/* * Copyright (C) 2012-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.pf4j.demo.welcome;
import com.et.pf4j.Greeting;import org.apache.commons.lang.StringUtils;
import org.pf4j.Extension;import org.pf4j.Plugin;import org.pf4j.PluginWrapper;import org.pf4j.RuntimeMode;
/** * @author Decebal Suiu */public class WelcomePlugin extends Plugin {
public WelcomePlugin(PluginWrapper wrapper) { super(wrapper); }
@Override public void start() { System.out.println("WelcomePlugin.start()"); // for testing the development mode if (RuntimeMode.DEVELOPMENT.equals(wrapper.getRuntimeMode())) { System.out.println(StringUtils.upperCase("WelcomePlugin")); } }
@Override public void stop() { System.out.println("WelcomePlugin.stop()"); }
@Extension public static class WelcomeGreeting implements Greeting {
@Override public String getGreeting() { return "Welcome ,my name is pf4j-plugin-01"; }
}
}

打成jar或者zip包,方便主程序加载

pf4j-app

加载插件包

package com.et.pf4j;
import org.pf4j.JarPluginManager;import org.pf4j.PluginManager;import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.nio.file.Paths;import java.util.List;
@SpringBootApplicationpublic class DemoApplication {
/* public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }*/ public static void main(String[] args) {

// create the plugin manager PluginManager pluginManager = new JarPluginManager(); // or "new ZipPluginManager() / new DefaultPluginManager()"
// start and load all plugins of application //pluginManager.loadPlugins();
pluginManager.loadPlugin(Paths.get("D:\\IdeaProjects\\ETFramework\\pf4j\\pf4j-plugin-01\\target\\pf4j-plugin-01-1.0-SNAPSHOT.jar")); pluginManager.startPlugins(); /* // retrieves manually the extensions for the Greeting.class extension point List<Greeting> greetings = pluginManager.getExtensions(Greeting.class); System.out.println("greetings.size() = " + greetings.size()); */ // retrieve all extensions for "Greeting" extension point List<Greeting> greetings = pluginManager.getExtensions(Greeting.class); for (Greeting greeting : greetings) { System.out.println(">>> " + greeting.getGreeting()); }
// stop and unload all plugins pluginManager.stopPlugins(); //pluginManager.unloadPlugins();

}}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springboot-demo

3.测试

运行DemoApplication.java 里面的mian函数,可以看到插件加载,调用以及卸载情况

4.引用

  • https://pf4j.org/

  • https://github.com/pf4j/pf4j-spring

相关推荐

  • 无人驾驶出租车爆火,武汉司机有些慌
  • 一个比requests还好用的Python高效爬虫库,效率提高一倍!
  • Modbus通信中到底用大端还是小端???
  • 29.8K Star谷歌都在用!!!超2万人关注的测试爬虫工具
  • 开源日报 | Vitest 2.0;谷歌专用API;通义千问“国服最强”;加州起草法案把开源管起来;汽车基础软件开源引热议
  • AI技术创新可以有多硬核?GOTC 2024论坛议程抢先看
  • Rust即将进入前十:中赢、大赢、还是特大赢?
  • 上交发布MG-LLaVA,基于多粒度指令调整,横扫视觉大模型榜单
  • 新国立祭出视频生成“无限宝石“:2300帧仅需5分钟,提速100倍
  • 中国AI论文数量全球第一!中科院拿下研究机构双第一,腾讯企业排第三
  • 阿尔特曼20年:从创业失败到权力中心
  • 最近很火的老照片动起来,都是怎么玩的?
  • 苹果Vision Pro和AI的重磅新大招,被提前扒出来了
  • 还在用Jenkins?快来试试这款简而轻的自动化部署工具吧!
  • Anthropic 最近高产Claude各种更新,openai 堪忧~
  • 鸿蒙新篇章:转转 APP 的 HarmonyOS Next 开发之旅
  • 红杉资本合伙人Pat Grady七月深度访谈 2万字全文(附视频)
  • 面试官:业务开发时,接口不能对外暴露怎么办?我有 3 种实现方案!
  • Java之父宣布退休!
  • 英雄联盟的“翻译官”卖了200多亿