PF4J使用


PF4J是一個Java輕量級的插件框架,可以實現動態加載,執行,卸載外部插件(支持jar以及zip),具體可以看官網:https://pf4j.org/

本文例子基於Github地址:https://github.com/pf4j/pf4j

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

插件項目會涉及到3個工程:工程結構

  • plugin-api:定義可擴展接口
  • plugins:插件項目,可以包含多個插件,需要實現plugin-api中定義的接口
  • plugin-app:主程序,需要依賴plugin-api,加載並執行plugins

定義可擴展接口(plugin-api)

簡單定義一個接口,需繼承ExtensionPoint

package plugin.api;

import org.pf4j.ExtensionPoint;

public interface Greeting extends ExtensionPoint {

String getGreeting();
}

實現插件(plugins)

插件需要實現plugin-api定義的接口,並且使用@Extension標記:

package plugins;

import org.pf4j.Extension;
import plugin.api.Greeting;

@Extension
public class WelcomeGreeting implements Greeting {

public String getGreeting() {
return "Welcome";
}
}

插件打包(plugins)

插件打包時,需要往MANIFEST.MF寫入插件信息,此處使用maven插件(打包命令為package):

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>welcome-plugin</Plugin-Id>
<Plugin-Version>0.0.1</Plugin-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>

 

根據Github上介紹,MANIFEST.MFPlugin-Id以及Plugin-Version是必須信息:

In above manifest I described a plugin with id welcome-plugin (mandatory attribute), with class org.pf4j.demo.welcome.WelcomePlugin (optional attribute), with version 0.0.1 (mandatory attribute) and with dependencies to plugins x, y, z (optional attribute).

此處定義插件ID為welcome-plugin,版本為0.0.1

加載執行插件(plugin-app)

package plugin.app;

import java.nio.file.Paths;
import java.util.List;

import org.pf4j.JarPluginManager;
import org.pf4j.PluginManager;

import plugin.api.Greeting;

public class Main {

public static void main(String[] args) {
// jar插件管理器
PluginManager pluginManager = new JarPluginManager();

// 加載指定路徑插件
pluginManager.loadPlugin(Paths.get("plugins-0.0.1-SNAPSHOT.jar"));

// 啟動指定插件(也可以加載所有插件)
pluginManager.startPlugin("welcome-plugin");

// 執行插件
List<Greeting> greetings = pluginManager.getExtensions(Greeting.class);
for (Greeting greeting : greetings) {
System.out.println(">>> " + greeting.getGreeting());
}

// 停止並卸載指定插件
pluginManager.stopPlugin("welcome-plugin");
pluginManager.unloadPlugin("welcome-plugin");

}
}



運行輸出:

>>> Welcome

其他

插件周期

如果對插件生命周期(如加載,執行,停止等)有興趣的話,可以實現插件類繼承Plugin

package plugins;

import org.pf4j.Plugin;
import org.pf4j.PluginWrapper;

public class WelcomePlugin extends Plugin {

public WelcomePlugin(PluginWrapper wrapper) {
super(wrapper);
}

@Override
public void start() {
System.out.println("WelcomePlugin.start()");
}

@Override
public void stop() {
System.out.println("WelcomePlugin.stop()");
}

@Override
public void delete() {
System.out.println("WelcomePlugin.delete()");
}
}

同時往MANIFEST.MF寫入插件信息:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>welcome-plugin</Plugin-Id>
<Plugin-Version>0.0.1</Plugin-Version>
<!-- 新增 -->
<Plugin-Class>plugins.WelcomePlugin</Plugin-Class>
</manifestEntries>
</archive>
</configuration>
</plugin>

打包后運行輸出:

WelcomePlugin.start()
>>> Welcome
WelcomePlugin.stop()

如果對運行流程感興趣,或者調試,可以將日志級別設為debug日志

 log4j.properties示例:

log4j.rootLogger = debug,stdout,log

log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d [%-5p] %l %r ms: %m%n

log4j.appender.log = org.apache.log4j.DailyRollingFileAppender
log4j.appender.log.DatePattern = _yyyy-MM-dd
log4j.appender.log.File = logs/debug.log
log4j.appender.log.Encoding = UTF-8
log4j.appender.log.layout = org.apache.log4j.PatternLayout
log4j.appender.log.layout.ConversionPattern = %d [%-5p] (%c.%t): %m%n


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM