Get into the habit of writing together! This is the 7th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .
foreword
A while ago, because of work, I needed to develop some plug-in functions, so I came up with this article " Tasting Java Dynamically Loading Jar Packages (1) ". I originally wanted to update an article related to dynamically generating Spring Beans . As a result, a big guy in the comment area recommended a Java plug-in related framework, which was really convenient to use, so I ruthlessly abandoned the original plan~~ ~~
Project engineering structure
├── rule 规则父模块
├── rule-api 规则定义接口
├── rule-plugins 规则插件Jar
└── rule-service 规则服务
复制代码
a
As the saying goes, if a worker wants to benefit his work, he must first sharpen his tools! Here we first establish the project foundation according to the above structure.
rule module
Create a new project, create three sub-projects under it, pom.xml
and introduce our protagonist pf4j .
<dependencies>
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
复制代码
rule-api module
rule-api , this module is used for the specification of the same plug-in module, which defines an interface, all plug-ins need to implement this interface, and rewrite the corresponding method to achieve specific logic.
step:
- Define an interface, inherit the
ExtensionPoint
interface - packaged and provided to other modules
/**
* 规则接口
*
* @author unidentifiable
* @date 2022/4/7 14:36
*/
public interface RuleApi extends ExtensionPoint {
/**
* 规则实现方法
*
* @param param 入参
* @return String
* @author unidentifiable
* @date 2022/4/7 14:37
*/
String ruleImplementationMethod(String param);
}
复制代码
After the interface definition is completed, it can be packaged and provided to other modules for reference.
rule-plugins
rule-plugins , plug-in module, this module needs to implement the interface defined by rule-api , and package it into a package after implementing the specific logic jar
. step:
pom
File import rule-api- Implement the
RuleApi
interface to implement specific rules and methods - Add the annotation @Extension to the class to declare that the class is an extended plugin class
- Packed into a
Jar
package, it should be noted here that you need to definePlugin-id
andPlugin-Version
<dependencies>
<dependency>
<groupId>com.unidentifiable</groupId>
<artifactId>rule-api</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>rule-plugin</Plugin-Id>
<Plugin-Version>1.0</Plugin-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
复制代码
/**
* 规则具体的实现
*
* @author unidentifiable
* @date 2022/4/7
*/
@Extension
public class RulePlugin implements RuleApi{
/**
* 规则实现
*
* @param param 入参
* @return String
* @author unidentifiable
* @date 2022/4/7 14:44
*/
@Override
public String ruleImplementationMethod(String param) {
return "(" + System.currentTimeMillis() + ")接收到参数:{" + param + "}";
}
}
复制代码
rule-service
rule-service , the business module, after receiving the request, loads the previously written Jar
package and executes the processing logic.
step:
pom
File import rule-api- Load the required plugins
- execution method
- return result
<dependencies>
<dependency>
<groupId>com.unidentifiable</groupId>
<artifactId>rule-api</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
复制代码
/**
* @author unidentifiable
* @date 2022/4/7
*/
public class RuleService {
public static void main(String[] args) {
// 插件ID
String plugin = "rule-plugin";
// 创建插件管理对象
JarPluginManager pluginManager = new JarPluginManager();
// 加载插件包
pluginManager.loadPlugin(Paths.get("F:\demo\rule\rule-plugins\target\rule-plugins-1.0.jar"));
// 启动指定的插件及其依赖项
pluginManager.startPlugin(plugin);
// 得到插件中定义的扩展类集合
List<RuleApi> extensions = pluginManager.getExtensions(RuleApi.class);
for (RuleApi ruleApi : extensions) {
// 执行方法
System.out.println(ruleApi.ruleImplementationMethod("测试插件"));
}
// 停用插件
pluginManager.stopPlugin(plugin);
// 卸载插件包
pluginManager.unloadPlugin(plugin);
}
}
复制代码
Effect
The basic functions are basically realized here. In the picture, we can see the effect of loading, and the logic implemented by the extension class is printed out in the console.
Plugin package extension
After loading the plug-in package above, what is obtained is a collection, then it means that the plug-in package can have multiple extension classes. So can we distinguish different logics by class name? Try it out~
rule-plugins
On the original basis, an additional extension class is added.
/**
* 规则具体的实现
*
* @author unidentifiable
* @date 2022/4/7
*/
@Extension
public class RulePlugin2 implements RuleApi{
/**
* 规则实现
*
* @param param 入参
* @return String
* @author unidentifiable
* @date 2022/4/7 14:44
*/
@Override
public String ruleImplementationMethod(String param) {
return "*****这里是新增的扩展类*****";
}
}
复制代码
After rewriting and packaging it, try the effect through rule-service !
As can be seen from the results, indeed all the extended classes have executed their related logic.
other
pf4j has many other functions, such as life cycle, spring
support, etc. Due to the limited time for fishing, I can only talk about this today and dig a hole. Small partners who are interested in this framework can also learn about other functions~~~