【Java】java插件化开发
java插件化开发
前言
最近使用JavaFx开发小工具,工具包含多个功能,当把小工具给同事用时,发现有些功能仅针对我个人使用,其他人不一定用的上,于是打算将这些工具插件化。
基本思路
java 程序多以jar形式存在,因此所谓插件就是一个个jar包,开发思路如下:
- 主程序定义插件接口;
- 插件项目引入主程序jar,并实现插件接口;
- 主程序通过类加载器加载插件jar中实现了插件接口的类。
详细步骤
插件开发
- 主程序中需要定义一个插件主入口的接口,这里定义为
indi.ta.worktools.ext.PluginService
,包含一个主入口方法void service()
:
public interface PluginService {
/**
* 插件运行方法
*/
void service();
}
- 在主程序中开放一些可以提供给插件程序调用的接口,比如:提供插件与主程序界面交互的方法;
- 将主程序打包成 jar 包,用来给插件项目作为依赖引入;
- 新建 Java 项目用来开发插件,引入主程序 jar 包作为依赖;
- 插件项目中提供一个实现了
indi.ta.worktools.ext.PluginService
接口的类,作为插件的主入口; - 项目类路径下添加 META-INF 目录,该目录下添加文件
plugin.json
,内容如下:
{
"name": "测试插件",
"version": "1.0",
"mainClass": "indi.testplugin.TestPlugin"
}
name
:插件名称;
version
:插件版本;
mainClass
:插件主类名(实现了indi.ta.worktools.ext.PluginService
接口的类.
- 将插件打成 jar 包(不需要包含3中引入的主程序jar),置于主程序的
plugins
目录(也可以自行指定目录)下;
插件加载
- 主程序定义插件类
Plugin
,用于封装从plugin.json
读取的插件信息,其中字段service
就是用来保存插件中实现了indi.ta.worktools.ext.PluginService
接口的类的实例:
public class Plugin {
/**
* 插件名称
*/
private String name;
/**
* 插件版本
*/
private String version;
/**
* 插件路径
*/
private String path;
/**
* 主类类名
*/
private String mainClass;
/**
* 实现类
*/
private PluginService service;
}
- 创建插件加载类,从插件目录中读取所有插件,
readPlugin()
方法用来从jar包中读取插件信息到Plugin
类中,调用插件的时候,通过Plugin
的PluginService service
调用service()
方法就可以唤起插件了
public class PluginLoader {
/**
* 加载所有插件,返回一个插件数组
*/
public static List<Plugin> load() throws Exception {
List<Plugin> plugins = new ArrayList<>();
File parentDir = new File("plugins");
File[] files = parentDir.listFiles();
if (null == files) {
return Collections.emptyList();
}
// 此处从 plug-ins 文件夹下加载所有插件
Plugin plugin;
String path;
for (File dir : files) {
if (!dir.isDirectory()) {
break;
}
// 插件jar包需与插件根目录同名
path = dir + System.getProperty("file.separator") + dir.getName() + ".jar";
plugin = readPlugin(path);
plugins.add(plugin);
}
return plugins;
}
/**
* 从插件jar包中读取 json 文件到 Plugin 类
*
* @param path jar 相对路径
*/
private static Plugin readPlugin(String path) throws IOException {
JarFile jarFile = new JarFile(path);
ZipEntry zipEntry = jarFile.getEntry("META-INF/plugin.json");
InputStream is = jarFile.getInputStream(zipEntry);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String temp;
StringBuilder sb = new StringBuilder();
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
Plugin plugin = null;
try {
plugin = JSON.parseObject(sb.toString(), Plugin.class);
plugin.setPath(path);
URL[] url = new URL[]{new URL("file:" + path)};
URLClassLoader loader = new URLClassLoader(url);
Class<?> clazz = loader.loadClass(plugin.getMainClass());
plugin.setService((PluginService) clazz.newInstance());
} catch (Exception e) {
new ExceptionAlter(e).show();
}
return plugin;
}
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员小航
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果