【仅供内部供应商使用,不提供对外解答和培训】
【仅供内部供应商使用,不提供对外解答和培训】
时间节点 | 说明 |
---|---|
加载(load) | 读取并生成PluginContext对象 添加插件间依赖的ClassPath 初始化插件接口的Class对象 读取证书 |
运行(run) | 检测插件依赖的文件 生成PluginClassLoader 检查并启动插件依赖的服务 生成插件接口对象,存放到各模块的ExtraClassManager中 |
停止(stop) | 从ExtraClassManager中删除对象 清空PluginContext中的对象 销毁PluginClassLoader 尝试停止服务依赖 |
禁用(forbid) | 停止运行(stop) 修改plugin.xml的active属性 |
启用(enable) | 修改plugin.xml的active属性 重新读取证书 运行(run) |
unload | 对应load 停止运行(stop) 删除PluginContext中加载的Class对象 删除PluginContext对象 |
安装(install) | 检测插件依赖的文件 检测插件依赖的服务 检测插件间依赖 安装依赖 安装插件(复制文件到插件Home) |
删除(uninstall) | 对应安装 检测依赖 删除文件 |
更新(update) | 停止运行(stop) 安装新版本插件 移动证书到新版本目录 删除旧插件
|
插件生命周期的各个节点如上表所示,插件中可以监听最重要的start和stop事件,在报表中可以监听所有事件,具体如下:
9.0插件支持热部署后,所有的插件都需要保证自己在被stop之后,能够释放所占用的资源。为了满足这样的需求,在插件中提供了lifecycle-monitor标签
<lifecycle-monitor class="com.fr.plugin.performance.base.manager.monitor.PerformancePluginMonitor"/>
指定的类需继承AbstractPluginLifecycleMonitor,如下:
/** * 内置监听,相当于性能插件的入口和出口 */ public class PerformancePluginMonitor extends AbstractPluginLifecycleMonitor { @Override public void afterRun(PluginContext context) { //do something } @Override public void beforeStop(PluginContext context) { //release resources } }
如方法名所示,afterRun是在运行之后调用的,beforeStop是在停止前调用。PluginContext用法见其他页面
2017年12月6日更新
在lifecycle-monitor中添加了三个事件,用于插件在特定节点做自定义的操作:afterInstall(安装后)、beforeUninstall(卸载前)、afterUpdate(更新后)。三个事件是独立的,在更新插件时不会触发安装和卸载事件。
AbstractPluginLifecycleMonitor中添加了这三个方法的默认回调,用于兼容未指定这三个事件的插件。
注意这三个事件都发生在插件运行周期以外的时间点,在ExtraClassManager中并没有当前插件的任何对象,所以这三个事件中不应该依赖任何跟插件运行相关的事务,而是作为对默认安装、卸载和更新流程的补充。
这三个事件近期发布。
可恢复任务主要用于保证stop后能够正确的释放资源,本质上也是监听的一种,具体用法见其他页面
除了在插件中监听自身的事件以外,报表中的某些需要缓存插件对象的地方也要监听特定插件的生命周期变动。为此插件模块提供了一套事件模型,用于方便的定制所需的监听。
PluginEventListener是所有插件监听的父类,定义了两个字段,用于对自身进行配置。派生类只需实现void on(PluginEvent)方法即可。
//生成一个监听,指定了优先级和作用域 PluginEventListener listener = new PluginEventListener(PluginListenerPriority.StableFactory, PluginListenerScope.ServletContextScope) { @Override public void on(PluginEvent event) { refreshJavaScriptFiles(); } };
PluginFilter是一个简单的接口,用来描述哪些PluginContext对象是符合条件的,在注册插件监听时,通常将一个PluginFilter与PluginEventListener绑定,共同传递给注册器,用来描述一个监听的目标插件是哪些。
PluginFilter filter = new PluginFilter() { @Override public boolean accept(PluginContext context) { //包含JavaScriptFileHandler的插件 return context.contain("JavaScriptFileHandler"); } };
PluginEventType枚举定义了所支持的事件,包括了本文开头表中描述的主要节点。
可以使用通用的GeneralContext来注册插件监听,也可以使用底层的PluginListenerRegistration来注册监听
//生成一个监听,指定了优先级和作用域 PluginEventListener listener = new PluginEventListener(PluginListenerPriority.StableFactory, PluginListenerScope.ServletContextScope) { @Override public void on(PluginEvent event) { refreshJavaScriptFiles(); } }; //过滤器 PluginFilter filter = new PluginFilter() { @Override public boolean accept(PluginContext context) { //包含JavaScriptFileHandler的插件 return context.contain("JavaScriptFileHandler"); } }; //注册监听,每当满足条件(包含JavaScriptFileHandler)的插件关闭时,刷新js文件 PluginListenerRegistration.getInstance().listen(PluginEventType.AfterStop,listener,filter);