-
Notifications
You must be signed in to change notification settings - Fork 28
YMP框架插件模块使用详解
插件有两种形式,主要区别是插件配置文件存放的方式不同:
-
一种是配置文件存放在插件jar包文件根路径下,这类插件须与工程类路径下其它依赖包一起使用;
-
另一种是配置文件存放在插件文件夹根目录下,这类插件可以放在工程路径以外,可以多模块共用插件,达到代码重用的效果,其目录结构如下:
<PLUGIN_HOME>\ |--.plugin\ // 插件全局通用类路径,将被插件根ClassLoader加载 | |--lib\ | | |--xxxx.jar | | |--... | |--classes\ | | |--... | |--... |--<plugin_id_xxx>\ // 插件目录,以Id为目录名称,将被插件自身ClassLoader加载 | |--lib\ | | |--xxxx.jar | | |--... | |--classes\ | | |--... | |--... | |--ymate_plugin.xml // 插件配置文件 |--<plugin_id_xxxx>\ |--...
插件配置必须命名为“ymate_plugin.xml”,格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="ymateweb.plugin.system" (1)
name="系统管理" (2)
alias="" (3)
class="net.ymate.web.plugin.system.SystemWebPlugin" (4)
author="suninformation" (5)
email="suninformation@163.com" (6)
version="1.0.0"> (7)
<automatic>true</automatic> (8)
<disabled>false</disabled> (9)
<extra-part></extra-part> (10)
<description></description> (11)
</plugin>
配置文件中各节点说明:
- (1) 插件的唯一标识,必须项,由开发人员确定命名规则,在相同JVM进程中不可重复,否则相同ID的插件,后者将覆盖前者;
- (2) 插件名称,无特殊要求,可根据需求自定义;
- (3) 别名,此为附加属性,可根据需求自定义;
- (4) 插件初始化类,此类需实现IPlugin接口,框架提供了AbstractPlugin抽象类,可直接继承;
- (5) 插件作者名称,此为附加属性;
- (6) 作者邮箱地址,此为附加属性;
- (7) 插件版本,此为附加属性;
- (8) 是否加载时自动启动运行,若设置为true,则插件将在首次被调用时进行启动和初始化;
- (9) 是否禁用当前插件,禁用的插件在插件加载过程中被忽略;
- (10) 插件扩展内容部分,为方便基于插件进行二次开发,特预留此项,可根据需求自定义其内容,同时需要提供实现了IPluginExtraParser接口的分析器来分析该部份配置信息;
- (11) 插件描述文字内容
以上配置文件结构是框架默认提供的,框架提供了插件工厂接口(IPluginFactory)和插件配置文件分析接口(IPluginParser)的默认实现,可自行扩展上述接口;
调用插件模块对象创建插件工厂,下列代码为使用默认配置,创建插件工厂实例对象:
IPluginFactory _factory = Plugins.createPluginFactory();
或者,通过默认配置对象,自定义插件配置扩展内容分析器和插件主目录,代码如下:
IPluginConfig _config = new DefaultPluginConfig(new WebPluginExtraParser(), Cfgs.smartSearch("plugins"));
IPluginFactory _factory = Plugins.createPluginFactory(_config);
也可以通过重新定义IPluginConfig接口,实现自定义插件配置,建议采用默认配置;
首先,定义新插件的业务接口,业务接口的作用是让其它业务程序能够访问到新插件,需要将此业务接口放置在全局的类路径下,样例业务接口如下:
public interface ITestBiz {
public String getBizName();
}
创建插件可以通过实现IPlugin接口或继承AbstractPlugin抽象类,代码如下:
-
通过IPlugin接口实现:
public class TestPlugin implements IPlugin, ITestBiz { public void destroy() throws PluginException { // TODO } public void doInit(PluginContext arg0) throws PluginException { // TODO } public void doStart() throws PluginException { // TODO } public void doStop() throws PluginException { // TODO } public PluginMeta getPluginMeta() { // TODO return null; } public String getBizName() { // TODO return null; } }
-
通过AbstractPlugin抽象类实现:
public class TestPlugin extends AbstractPlugin implements ITestBiz { public void doStart() throws PluginException { // TODO } public void doStop() throws PluginException { // TODO } public String getBizName() { // TODO return null; } }
获取插件实例对象可以通过插件Id和业务接口完成,根据上例代码,获取TestPlugin实例并调用ITestBiz业务方法,代码如下:
-
通过插件Id调用方式:
IPluginFactory _factory = Plugins.createPluginFactory(); ITestBiz _biz = (ITestBiz) _factory.getPlugin("test"); System.out.println(_biz.getBizName());
-
通过业务接口调用方式:
IPluginFactory _factory = Plugins.createPluginFactory(); ITestBiz _biz = _factory.getPlugin(ITestBiz.class); System.out.println(_biz.getBizName());
若想屏蔽某些业务接口,可以通过下面的方式实现:
DefaultPluginFactory.addExcludedInterfaceClass(ITestBiz.class);
上面的代码执行后,将无完通过ITestBiz接口获取到插件实例对象;
若多个插件实现了同一个业务接口,根据插件加载顺序,最后加载的插件实例对象将替换前者;
通过PluginUtils工具类,可以帮助完成插件路径下相关资源文件的加载:
-
资源文件加载:
IPluginFactory _factory = Plugins.createPluginFactory(); // PluginUtils.getResourcePath("cfgs/test.cfg.xml", _factory.getPlugin("test")); PluginUtils.getResourceFile("cfgs/test.cfg.xml", _factory.getPlugin("test"));
-
配置对象填充:
IPluginFactory _factory = Plugins.createPluginFactory(); // TestConfig _config = new TestConfig(); PluginUtils.getResourceFile(_config, "cfgs/test.cfg.xml", _factory.getPlugin("test")); PluginUtils.getResourceFile(_config, _factory.getPlugin("test"));