六、入侵Activiti-SpringBoot使用代码动态编辑流程文件

来源:互联网 发布:中文数据库有哪些 编辑:程序博客网 时间:2024/05/08 19:42

需求总是变来变去,产品希望可以实现动态改变工作流程,从而提高系统的灵活性。这就让我有点懵逼了。

查了一些资料,有两种实现方式:

  1. 前端页面生成bpmn文件,传送给后台,但是对前端的要求比较高。
  2. 使用Java代码动态更改流程文件,达到修改流程的目的。

这里使用代码的方式来实现,接下来使用一个Demo做一个简单的示例。

一、使用Activiti Modeler画一个流程图

该流程图会保存到数据库的ACT_REP_MODEL表中。

流程图定义如下:
整体定义

这里写图片描述

开始定义

这里写图片描述

开始和userTask的箭头定义

这里写图片描述

userTask定义

这里写图片描述

userTask和结束的箭头定义

这里写图片描述

结束定义

这里写图片描述

二、项目中需要引入的依赖

//Activiticompile('org.activiti:activiti-spring-boot-starter-basic:5.22.0')compile('org.activiti:activiti-modeler:5.22.0'){        //排除Security依赖,否则需要输入密码才能访问项目        exclude group: 'org.springframework.security'    }//布局排版,当使用代码编辑流程图时,需要自动排版,否则会因为找不到位置信息而报错compile group: 'org.activiti', name: 'activiti-bpmn-layout', version: '5.22.0'

三、使用代码修改流程图

只是个Demo,很多数据是硬编码,熟悉原理后,可以自己写活。注释都写清楚了,不多解释。

import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.node.ObjectNode;import org.activiti.bpmn.BpmnAutoLayout;import org.activiti.bpmn.converter.BpmnXMLConverter;import org.activiti.bpmn.model.BpmnModel;import org.activiti.bpmn.model.Process;import org.activiti.bpmn.model.SequenceFlow;import org.activiti.bpmn.model.UserTask;import org.activiti.editor.language.json.converter.BpmnJsonConverter;import org.activiti.engine.RepositoryService;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.io.*;/** * @author kingboy--KingBoyWorld@163.com * @date 2017/8/31 下午2:39 * @desc 这块是很重要的核心代码,用代码来编辑流程图. */@RestController@RequestMapping("/modify")public class ModifyController {    //注入Activiti的RepositoryService    @Resource    RepositoryService repositoryService;    //    @RequestMapping(value = "/modify", method = RequestMethod.GET)    public void modifyBPMN() throws IOException {        //读取指定ID的Model的二进制资源,是Json格式的。        byte[] modelSource = repositoryService.getModelEditorSource("3");        //使用jackson将Model的源信息转换为JsonNode对象        ObjectMapper mapper = new ObjectMapper();        JsonNode jsonNode = mapper.readTree(modelSource);        //创建一个bpmn的json转换器        BpmnJsonConverter jsonConverter = new BpmnJsonConverter();        //将jsonNode对象转换为bpmnModel的对象        BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(jsonNode);        //读取bpmnModel中id为process的流程定义        Process process = bpmnModel.getProcessById("process");        //创建一个UserTask任务,id为b3,        UserTask userTask = new UserTask();        userTask.setId("b3");        userTask.setName("userTask2");        userTask.setAssignee("小金");        //添加到流程中        process.addFlowElement(userTask);        //移除开始和userTask1之间的a2箭头,        process.removeFlowElement("a2");        //创建一个新的箭头从b2指向b3,也就是从userTask1连接到userTask2        SequenceFlow flow1 = new SequenceFlow();        flow1.setSourceRef("b2");        flow1.setTargetRef("b3");        //创建一个新的箭头从b3指向b4,也就是从userTask2连接到结束事件        SequenceFlow flow2 = new SequenceFlow();        flow2.setSourceRef("b3");        flow2.setTargetRef("b4");        //将两个箭头添加到流程定义中        process.addFlowElement(flow1);        process.addFlowElement(flow2);        //对文件进行重新排版,生成位置信息,否则会报错        new BpmnAutoLayout(bpmnModel).execute();        //创建一个bpmn的xml转换器,        BpmnXMLConverter xmlConverter = new BpmnXMLConverter();        //这里将结果输出到一个文件中,查看是否成功,(必需成功)        byte[] bytes = xmlConverter.convertToXML(bpmnModel);        FileOutputStream fileOutputStream = new FileOutputStream("/Users/kingboy/Desktop/MyDIY.bpmn");        fileOutputStream.write(bytes);        fileOutputStream.close();    }}

最终生成的流程图如下:

这里写图片描述

虽然只是个Demo,但是其中可以演化出很多技能。比如说,我们拿到了bpmn的xml流了,那么肯定就可以直接部署到引擎中了。

这个Demo是修改已有的流程,那么我们可不可以用代码直接新建一个流程图呢?当然是可以的,只要认真看下涉及到的几个类的API,就很容易了。

学的是思想而不能仅仅局限于技术。

阅读全文
0 0