• 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

    导入依赖

    1. <dependency>
    2. <groupId>org.pf4j</groupId>
    3. <artifactId>pf4j</artifactId>
    4. <version>3.0.1</version>
    5. </dependency>

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

    1. package com.et.pf4j;
    2. import org.pf4j.ExtensionPoint;
    3. public interface Greeting extends ExtensionPoint {
    4. String getGreeting();
    5. }

    打包给其他项目引用

    pf4j-plugins-01

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

    1. /*
    2. * Copyright (C) 2012-present the original author or authors.
    3. *
    4. * Licensed under the Apache License, Version 2.0 (the "License");
    5. * you may not use this file except in compliance with the License.
    6. * You may obtain a copy of the License at
    7. *
    8. * http://www.apache.org/licenses/LICENSE-2.0
    9. *
    10. * Unless required by applicable law or agreed to in writing, software
    11. * distributed under the License is distributed on an "AS IS" BASIS,
    12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13. * See the License for the specific language governing permissions and
    14. * limitations under the License.
    15. */
    16. package org.pf4j.demo.welcome;
    17. import com.et.pf4j.Greeting;
    18. import org.apache.commons.lang.StringUtils;
    19. import org.pf4j.Extension;
    20. import org.pf4j.Plugin;
    21. import org.pf4j.PluginWrapper;
    22. import org.pf4j.RuntimeMode;
    23. /**
    24. * @author Decebal Suiu
    25. */
    26. public class WelcomePlugin extends Plugin {
    27. public WelcomePlugin(PluginWrapper wrapper) {
    28. super(wrapper);
    29. }
    30. @Override
    31. public void start() {
    32. System.out.println("WelcomePlugin.start()");
    33. // for testing the development mode
    34. if (RuntimeMode.DEVELOPMENT.equals(wrapper.getRuntimeMode())) {
    35. System.out.println(StringUtils.upperCase("WelcomePlugin"));
    36. }
    37. }
    38. @Override
    39. public void stop() {
    40. System.out.println("WelcomePlugin.stop()");
    41. }
    42. @Extension
    43. public static class WelcomeGreeting implements Greeting {
    44. @Override
    45. public String getGreeting() {
    46. return "Welcome ,my name is pf4j-plugin-01";
    47. }
    48. }
    49. }

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

    pf4j-app

    加载插件包

    1. package com.et.pf4j;
    2. import org.pf4j.JarPluginManager;
    3. import org.pf4j.PluginManager;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. import java.nio.file.Paths;
    6. import java.util.List;
    7. @SpringBootApplication
    8. public class DemoApplication {
    9. /* public static void main(String[] args) {
    10. SpringApplication.run(DemoApplication.class, args);
    11. }*/
    12. public static void main(String[] args) {
    13. // create the plugin manager
    14. PluginManager pluginManager = new JarPluginManager(); // or "new ZipPluginManager() / new DefaultPluginManager()"
    15. // start and load all plugins of application
    16. //pluginManager.loadPlugins();
    17. pluginManager.loadPlugin(Paths.get("D:\\IdeaProjects\\ETFramework\\pf4j\\pf4j-plugin-01\\target\\pf4j-plugin-01-1.0-SNAPSHOT.jar"));
    18. pluginManager.startPlugins();
    19. /*
    20. // retrieves manually the extensions for the Greeting.class extension point
    21. List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
    22. System.out.println("greetings.size() = " + greetings.size());
    23. */
    24. // retrieve all extensions for "Greeting" extension point
    25. List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
    26. for (Greeting greeting : greetings) {
    27. System.out.println(">>> " + greeting.getGreeting());
    28. }
    29. // stop and unload all plugins
    30. pluginManager.stopPlugins();
    31. //pluginManager.unloadPlugins();
    32. }
    33. }

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

    代码仓库

    3.测试

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

    4.引用

  • 相关阅读:
    2023计算机毕业设计选题推荐——Java项目
    大厂面试总结大全二
    多功能频率计周期/脉宽/占空比/频率测量verilog,视频/代码
    vue之搭建脚手架快速创建vue项目
    Android源码——Rect源码解析
    ESP8266-Arduino编程实例-L9110直流电机驱动
    分布式事务 —— SpringCloud Alibaba Seata
    伪原创-伪原创软件-免费伪原创软件
    CentOS 安装 Docker
    java-php-python-ssm学校旧书交易网站计算机毕业设计
  • 原文地址:https://blog.csdn.net/dot_life/article/details/140335823