pf4j-spring使用

最近项目中需要做自定义配置的功能,希望调用方配置自己的代码来实现相关功能,正好pf4j这个轻量的插件库可以实现,写了个demo验证了下功能

一、maven

<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j-spring</artifactId>
<version>0.6.0</version>
</dependency>

二、代码实现

分为三个项目模块:

  • 接口定义 pf4j-api:定义接口行为
  • 插件实现 pf4j-plugin:实现插件能力
  • 插件加载 pf4j-use:使用插件
2.1 接口定义
public interface Greeting extends ExtensionPoint {

String getGreeting();
}
2.2 插件实现
// 继承了Plugin 可以介入插件的生命周期
public class HelloPlugin extends Plugin {

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

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

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

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

// 插件具体实现
@Extension
public static class HelloGreeting implements Greeting {
@Override
public String getGreeting() {
return "hello world";
}
}
}

同时需要配置pom

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestEntries>
<!-- 这些属性是PluginManager 加载的时候需要 -->
<Plugin-Id>hello-plugin</Plugin-Id>
<Plugin-Version>0.0.1</Plugin-Version>
<Plugin-Class>com.juststand.pf4j.consumer.HelloPlugin</Plugin-Class>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>

将代码打成jar后,解压jar,在META-INF文件夹下有两个文件

extensions.idx 和 MANIFEST.MF,这两个是必须要的,maven项目打包会自动生成

插件加载时,需要读取里面的属性

2.3 加载插件

我用springboot项目,直接注入SpringPluginManager对象到容器上

@Configuration
public class SpringConfiguration {

@Bean
public SpringPluginManager pluginManager() {
return new SpringPluginManager();
}

}
@RestController
public class DemoController {

@Autowired
private PluginManager pluginManager;

private String pluginId;

/**
* 加载插件,活返回对应的 pluginId,这个id是插件中配置的
*/
@RequestMapping("/load")
public String test() {
File file = new File("D:/pf4j-consumer-1.0.0.jar");
return pluginManager.loadPlugin(file.toPath());
}

/**
* 启动插件,进行调用
*/
@RequestMapping("/do")
public String deal() {
pluginManager.startPlugin(pluginId);
List<Greeting> extensions = pluginManager.getExtensions(Greeting.class, pluginId);
String res = null;
for (Greeting extension : extensions) {
res = extension.getGreeting();
}
return res;
}
}

三、参考

GitHub - pf4j 官方代码里面有相关描述,代码介绍