【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

插件生命周期说明

 

时间节点
说明
加载(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事件,在报表中可以监听所有事件,具体如下:

插件中监听自身的start和stop事件

9.0插件支持热部署后,所有的插件都需要保证自己在被stop之后,能够释放所占用的资源。为了满足这样的需求,在插件中提供了lifecycle-monitor标签

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后能够正确的释放资源,本质上也是监听的一种,具体用法见其他页面

细粒度的定义监听

除了在插件中监听自身的事件以外,报表中的某些需要缓存插件对象的地方也要监听特定插件的生命周期变动。为此插件模块提供了一套事件模型,用于方便的定制所需的监听。

1.监听

PluginEventListener是所有插件监听的父类,定义了两个字段,用于对自身进行配置。派生类只需实现void on(PluginEvent)方法即可。

  1. priority:优先级,如果某事件存在多个监听,则优先级决定了执行顺序,级别越高越先执行。
  2. scope:监听的作用域。该字段可以用于自动移除监听,比如只想监听到Servlet关闭,则可以指定该字段为PluginListenerScope.ServletContextScope,这样在Servlet关闭时,会自动清除这个监听,免去了手动移除所带来的复杂性。
监听示例
//生成一个监听,指定了优先级和作用域
PluginEventListener listener = new PluginEventListener(PluginListenerPriority.StableFactory, PluginListenerScope.ServletContextScope) {
    
    @Override
    public void on(PluginEvent event) {
       
        refreshJavaScriptFiles();
    }
};
2.插件过滤器

PluginFilter是一个简单的接口,用来描述哪些PluginContext对象是符合条件的,在注册插件监听时,通常将一个PluginFilter与PluginEventListener绑定,共同传递给注册器,用来描述一个监听的目标插件是哪些。

过滤器
PluginFilter filter = new PluginFilter() {
    
    @Override
    public boolean accept(PluginContext context) {
        //包含JavaScriptFileHandler的插件
        return context.contain("JavaScriptFileHandler");
    }
};
3.事件

PluginEventType枚举定义了所支持的事件,包括了本文开头表中描述的主要节点。

4.注册

可以使用通用的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);
  • No labels