扩展Activiti工作流任务和属性

用过activiti的朋友都知道,activiti做工作流用起来非常方便,可以很容易的基于activiti开发出一个基础的OA流程,可以有多种任务,事件,网关提供给大家选择,想了解详细的,可以点击下方链接多了解,网上资料也特别多,这里不再赘述。

下面给出几个快速入门的链接:
咖啡兔的demo英文版activti使用手册中文版用户手册

但是最近做了一个项目要求是:

  • 通过web访问的可视化可扩展的流程设计器
  • 可以定制任务节点
  • 可以扩展任务属性

这一下懵逼了,三个问题都不简单

首先,activiti虽然自带一个web设计器activiti modeler,但是如果要支持自定义任务节点和扩展节点属性,很难修改,而且修改之后activiti引擎并不识别。
然后就是我们扩展的任务节点和任务属性activiti引擎不识别的问题。

结果就是面对着activiti这个金矿却无从下手,而且如果要硬生生开发出一个activiti的新的任务节点,就得深入剖析activiti的代码,工作量和难度都非常大,最后只能决定曲线救国,看看activiti有没有什么现成的任务能支持扩展属性,如果有,这样就可以同时解决扩展属性的问题了,翻了翻用户手册,发现activiti有个任务节点叫ServiceTask,眼睛一亮这不就是我想要的么。ServiceTask参考

ServiceTask Description 描述

Java 服务任务用来调用外部 Java 类

XML representation 内容

有4钟方法来声明 java 调用逻辑:

  • 实现 JavaDelegate 或 ActivityBehavior
  • 执行解析代理对象的表达式
  • 调用一个方法表达式
  • 调用一直值表达式

执行一个在流程执行中调用的类, 需要在'activiti:class'属性中设置全类名,这个类设置后,流程执行到serviceTask这一步时就会自动调用这个java类。

<serviceTask id="javaService"  name="My Java Service Task" 
    activiti:class="com.yang.activiti.demo.service.ServiceTaskService" />

注意,如果使用了spring mvc框架,默认配置的 activiti:class 是不能通过注解注入类的,如果想要通过注解注入java类,需要使用如下语法

<serviceTask id="serviceTask" activiti:delegateExpression="${serviceTaskService}" />

serviceTaskService是一个实现了 JavaDelegate 接口的bean, 它定义在实例的 spring 容器中

serviceTask还可以注入多个参数

<serviceTask id="ServiceTaskService" 
    name="ServiceTaskService" 
    activiti:class="com.yang.activiti.demo.service.ServiceTaskService">
  <extensionElements>   
    <activiti:field name="param1">
        <activiti:string> Hello World</activiti:string>
    </activiti:field>
  <activiti:field name="param2">
        <activiti:string> Hello World</activiti:string>
    </activiti:field>
  </extensionElements>        
</serviceTask>  

java后台com.yang.activiti.demo.service.ServiceTaskService

public class ServiceTaskService implements JavaDelegate {

  private Expression param1;
  private Expression param2;

  public void execute(DelegateExecution execution) {
    String value1 = (String) param1.getValue(execution);
    execution.setVariable("var1", new StringBuffer(value1).reverse().toString());

    String value2 = (String) param2.getValue(execution);
    execution.setVariable("var2", new StringBuffer(value2).reverse().toString());
  }
}

还有其他的参数属性去参照ServiceTask参考不得不说这个节点真的很灵活。


至此我发现了ServiceTask的两个重要特性:

1. 可以绑定自定义的java class(这不就是我想要的扩展自定义任务么)
2. 可以传递无限多个参数(这不就是我想要的扩展属性么)

基于ServiceTask可以有无限多的可能。
这样基本解决了以下两个大问题

  • 可以定制任务节点
  • 可以扩展任务属性

下面就剩下一个问题

  • 通过web访问的可视化可扩展的流程设计器

然后就继续调研,发现activiti modeler我是肯定用不了了,原因如下:

  • 因为要使用serviceTask扩展任务节点,就要涉及复制出多个serviceTask节点,结果发现复制出的serviceTask节点会将原生的serviceTask节点功能覆盖,也就是说只能同时存在一个serviceTask节点
  • 复制出来的serviceTask节点扩展属性,例如:param1,param2,activiti引擎根本不认识,会报错

所以不能用自带的activiti modeler,那么就得去寻找一个流程设计器替代品,替代品有如下要求:

  • 代码结构尽量简单
  • 可以将设计好的流程保存为格式化数据,例如json,xml等
  • 扩展性好
  • 好集成

找了老半天,有很多不错的设计器,但是都不太满足要求,最后还是万能的github帮了我,找到了一个大神开发的一款基于js的可拖拽流程设计器,可以将设计好的流程保存为json格式,双手附上链接LarryleWorkFlow,同时也谢谢作者wangyue20075,设计器的主页是这样子的:

设计器的主页.PNG

通过作者的工具类可以很容易的去扩展属性,扩展任务,然后将结果保存为json。

下面问题又来了:
保存的json activiti不认识
这个就需要我们自己去写activiti的task解释器了,将我们读取到的json解释成acitivi可以认识的xml,保存在数据库中,然后读取我们的xml去调用activiti的接口发布。

repositoryService.createDeployment() .name(workflowDesigner.getFlowId())
 .addString(processName, flowBpmnXml).deploy();

下面贴一段我的代码:

@RequestMapping("deployFlow/{flowId}")
    @ResponseBody
    public Map<String,Object> deployFlow(@PathVariable("flowId") String flowId){
        Map<String,Object> result = new HashMap<String,Object>();
        workflowDesigner workflowDesigner = workflowDesignerService.selectByPrimaryKey(flowId);
        String flowBpmnXml = workflowDesigner.getFlowBpmnXml();
        String processName = workflowDesigner.getFlowId() + ".bpmn20.xml";
        logger.debug("processName is : "+processName);
        try {
            Deployment deployment = repositoryService.createDeployment()
                                                     .name(workflowDesigner.getFlowId())
                                                     .addString(processName, flowBpmnXml).deploy();
            ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId());
            ProcessDefinition processDefinition = query.singleResult();
            result.put("code",1);
            result.put("message",processDefinition.getId());
        } catch (Exception e) {
            result.put("code",0);
            result.put("message",e.getMessage());
            logger.error(e.getMessage());
        }
        logger.debug(result.toString());
        return result;
    }

这样就完成了一个自定义任务的定义,创建,发布的过程,以上仅仅是个人的思路,欢迎大家讨论或提出意见。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容