阅读量:5
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"); } }