PF4J+SpringBoot

plugin-common

pom.xml相关配置

<groupId>pub.qingyun</groupId>
<artifactId>plugin-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<description>插件配置类</description>

<dependency>
     <groupId>org.pf4j</groupId>
     <artifactId>pf4j</artifactId>
     <version>3.12.0</version>
</dependency>
 <!--插件打包时使用的Maven插件,插件ID:Plugin-Id,使用mvn clean package 打出*jar-with-dependencies.jar的插件包-->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                    </manifest>
                    <manifestEntries>
                        <Plugin-Id>common-impl</Plugin-Id>
                        <Plugin-Version>0.0.1</Plugin-Version>
                    </manifestEntries>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

插件服务接口

pub.qingyun.service.IExtensionHandler

public interface IExtensionHandler extends Runnable, ExtensionPoint {
    String execute(String param);
}

实现类

import org.pf4j.Extension;
import pub.qingyun.service.IExtensionHandler;

@Extension
public class TestExtensionHandler implements IExtensionHandler {
    @Override
    public void run() {
        System.out.println("TestExtensionHandler run...");
    }

    @Override
    public String execute(String param) {
        System.out.println("TestExtensionHandler.execute...param=" + param);
        return param;
    }
}

plugin-spring-boot

pom.xml相关配置

<groupId>pub.qingyun</groupId>
<artifactId>plugin-spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>plugin-spring-boot</name>
<description>plugin-spring-boot</description>

<properties>
     <java.version>1.8</java.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
     <spring-boot.version>2.6.13</spring-boot.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>pub.qingyun</groupId>
        <artifactId>plugin-common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    ...
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

spring-boot

@Configuration
public class PluginConfig {
    
    // 插件目录,对应插件jar包/zip
    @Value("${pf4j.pluginPath}")
    private String pf4jPluginPath;

    @Bean
    public PluginManager initPluginManager() {

        Path pluginPath = Paths.get(pf4jPluginPath);
        PluginManager pluginManager = new JarPluginManager(pluginPath);

        //加载所有插件
        pluginManager.loadPlugins();


        //开启所有插件
        pluginManager.startPlugins();

        //启动指定插件
//        pluginManager.startPlugin("demo-plugin");

        //卸载插件
//        pluginManager.unloadPlugin("demo-plugin");
        return pluginManager;
    }
}

控制层实现

package pub.qingyun.controller;

import lombok.extern.slf4j.Slf4j;
import org.pf4j.PluginManager;
import org.pf4j.PluginState;
import org.pf4j.PluginWrapper;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import pub.qingyun.service.impl.TestExtensionHandler;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author CQY
 * @version 1.0
 * @date 2024/7/17 14:19
 **/
@Slf4j
@RestController
public class PluginController {

    @Resource
    private PluginManager pluginManager;

    /**
     * 打印所有插件信息
     *
     * @return List<Map < String, Object>>
     */
    @GetMapping(value = "/printAllPlugin")
    public ResponseEntity<List<Map<String, Object>>> printAllPlugin() {
        List<PluginWrapper> plugins = pluginManager.getPlugins();
        List<Map<String, Object>> collect = plugins.stream().map((item) -> {
            Map<String, Object> map = new HashMap<>();
            map.put("pluginId", item.getPluginId());
            map.put("pluginDescription", item.getDescriptor());
            map.put("pluginPath", item.getPluginPath());
            map.put("pluginState", item.getPluginState());
            map.put("pluginClassLoader", item.getPluginClassLoader());
            return map;
        }).collect(Collectors.toList());
        return ResponseEntity.ok(collect);
    }

    /**
     * 启动插件
     *
     * @param pluginId 插件id
     * @return PluginState
     */
    @GetMapping(value = "/startPluginById")
    public ResponseEntity<String> startPluginById(String pluginId) {
        PluginState pluginState = pluginManager.startPlugin(pluginId);
        return ResponseEntity.ok(pluginState.toString());
    }

    /**
     * 停止插件
     *
     * @param pluginId 插件id
     * @return PluginState
     */
    @GetMapping(value = "/stopPluginById")
    public ResponseEntity<String> stopPluginById(String pluginId) {
        PluginState pluginState = pluginManager.stopPlugin(pluginId);
        return ResponseEntity.ok(pluginState.toString());
    }

    /**
     * 禁用插件
     *
     * @param pluginId 插件id
     * @return boolean true表示成功
     */
    @GetMapping(value = "/disablePluginById")
    public ResponseEntity<Boolean> disablePluginById(String pluginId) {
        boolean result = pluginManager.disablePlugin(pluginId);
        return ResponseEntity.ok(result);
    }

    /**
     * 启用插件
     *
     * @param pluginId 插件id
     * @return boolean true表示成功
     */
    @GetMapping(value = "/enablePluginById")
    public ResponseEntity<Boolean> enablePluginById(String pluginId) {
        boolean result = pluginManager.enablePlugin(pluginId);
        return ResponseEntity.ok(result);
    }

    /**
     * 卸载插件
     *
     * @param pluginId 插件id
     * @return boolean true表示成功
     */

    @GetMapping(value = "/unloadPluginById")
    public ResponseEntity<Boolean> unloadPluginById(String pluginId) {
        boolean result = pluginManager.unloadPlugin(pluginId);
        return ResponseEntity.ok(result);
    }

    /**
     * 加载插件
     *
     * @return String
     */
    @GetMapping(value = "/loadPlugins")
    public ResponseEntity<String> loadPlugins() {
        pluginManager.loadPlugins();
        //开启所有插件
        pluginManager.startPlugins();
        return ResponseEntity.ok("SUCCESS");
    }

    /**
     * 执行插件中的扩展点
     *
     * @param pluginId 插件id
     * @return String 执行结果
     */
    @GetMapping(value = "/executePluginExtensionHandlerById")
    public ResponseEntity<String> executePluginExtensionHandlerById(String pluginId) {
        List<Class<?>> extensionClasses = pluginManager.getExtensionClasses(pluginId);
        for (Class<?> extensionClass : extensionClasses) {
            if (extensionClass.getName().equals("pub.qingyun.service.impl.TestExtensionHandler")) {
                try {
                    Class<?> clz = Class.forName("pub.qingyun.service.impl.TestExtensionHandler", true, Thread.currentThread().getContextClassLoader());
                    TestExtensionHandler extensionHandler = (TestExtensionHandler) clz.newInstance();
                    String execute = extensionHandler.execute("hello");
                    extensionHandler.run();
                } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return ResponseEntity.ok("SUCCESS");
    }
}

相关推荐

  1. PF4J+SpringBoot

    2024-07-18 11:04:03       20 阅读
  2. PX4 Bug汇总

    2024-07-18 11:04:03       55 阅读
  3. 4-Docker命令之docker ps

    2024-07-18 11:04:03       46 阅读
  4. neo4j-Py2neo使用

    2024-07-18 11:04:03       54 阅读
  5. 【无人机】PIXHAWK、PX4、APM区别

    2024-07-18 11:04:03       64 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 11:04:03       70 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 11:04:03       74 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 11:04:03       62 阅读
  4. Python语言-面向对象

    2024-07-18 11:04:03       72 阅读

热门阅读

  1. CAS的原理

    2024-07-18 11:04:03       27 阅读
  2. P5717 【深基3.习8】三角形分类

    2024-07-18 11:04:03       21 阅读
  3. 【数据平台-dataworks】-问题总结

    2024-07-18 11:04:03       23 阅读
  4. spring中的依赖注入

    2024-07-18 11:04:03       21 阅读
  5. 力扣212题:单词搜索 II

    2024-07-18 11:04:03       21 阅读
  6. Go语言学习

    2024-07-18 11:04:03       22 阅读
  7. Spring Boot集成ShardingSphere详解

    2024-07-18 11:04:03       21 阅读
  8. 石油与化工行业的工业互联网平台革新之路

    2024-07-18 11:04:03       23 阅读