1、特 别 响 、 非 常 近 BPMN2新 规 范 与 Activiti5作者 晁扬扬 发布于 2012 年 4 月 25 日领域企业架构, 架构 /使用 repositoryService 进行新流程部署repositoryService.createDeployment().addClasspathResource(“请假申请-条件分支与合并流程.bpmn20.xml“).deploy();Step4:创建请假单页面输入请假天数及原由,启动流程编写 html 表单输入界面,然后使用 Ajax 提交请求,由 Servlet 根据请求参数创建新流程实例,启动流程后界面如图 4:图 4:流程启动后
2、的界面输入请假天数及原因,如果天数大于等于 3 天,则走“部门经理审批路由“分支,利用 jQuery 绑定”提交“按钮的操作:$(#startProcess).click(function()varurl = /com.ygsoft.process.demo/ProcessEngineServlet?operate=start /以 UTF8 方式提交:$.ajax(url:url,type:“POST“,dataType:“json“,contentType:“application/x-www-form-urlencoded;charset=utf-8“,/此参数避免中文乱码success
3、:function(data)if(data.success)alert(您的单据已提交,流程 ID:+data.id);$(#inputform).hide();$(#viewTodo).show(2000);elsealert(您的单据未提交成功); );)Backend 端利用 RuntimeService 接口创建新的流程实例:/ 通过 ProcessEngine 获取 runtimeServiceRuntimeServiceruntimeService = processEngine.getRuntimeService();/ 使从 Request 中获取请求参数,用于构造流程启动参
4、数Mapparams = newHashMap();String processKey = request.getParameter(“processKey“); int day = Integer.parseInt(request.getParameter(“day“);String reason = request.getParameter(“reason“);params.put(“day“, day);params.put(“user“, user);params.put(“reason“, reason); / 使用 runtimeService 启动流程实例(将参数做为流程变量处理
5、)ProcessInstanceprocessInstance = runtimeService.startProcessInstanceByKey(processKey,params) ; Step5:获取审批人待办任务利用 TaskService 接口可是实现指配给自己的以及候选任务:/ 通过 ProcessEngine 获取 taskServiceTaskServicetaskService = processEngine.getTaskService();/ 使用 taskService 根据用户 ID 获取候选任务List tasks = taskService.createTask
6、Query().taskAssignee(user).orderByTaskCreateTime().desc().list();将查询到的 List 通过 Gson 转换成 json 数组传递到前端,由 jQuery 解析并显示到界面。还有一种情况是查询分配给某个组或某个人的候选任务:List tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId().taskCandidateGroup(“xxxGrp“).list();/ 或List tasks = taskService.createT
7、askQuery().processInstanceId(processInstance.getId().taskCandidateUser(“xxxUser“).list();Step6:审批人查看任务明细任务明细除了包含 Task 本身的信息(如任务名称、描述以及流程变量等)外,还要动态显示当前激活任务的可视化流程图。Task 信息可以从 List 中获取,可视化流程图可以利用以下方式输出至前端:/ 根据当前 Task 获取流程定义对象 ProcessDefinitionEntityprocessDefinition = (ProcessDefinitionEntity) (Reposit
8、oryServiceImpl) repositoryService) .getDeployedProcessDefinition(task.getProcessDefinitionId(); / 利用 ProcessDiagramGenerator 生成当前激活任务的图片流 InputStreamdefinitionImageStream = ProcessDiagramGenerator.generateDiagram(processDefinition, “png“, runtimeService.getActiveActivityIds(task.getProcessInstanceId
9、(); / 将图片流生成 byte数组 byte diagramBytes = IoUtil.readInputStream(definitionImageStream,null); response.setContentType(“image/png“);/ 设置浏览器响应的 ContentType ServletOutputStream out = response.getOutputStream(); out.write(diagramBytes);/ 输出至前端 out.close();Step7:完成审批任务审批人在查看请假申请单后,填写审批意见后以 Ajax 方式提交“完成任务“请
10、求;Servlet 利用 TaskService 进行任务的提交:/先完成当前任务: Mapparams = taskService.getVariables(taskId); String reviewMessage = request.getParameter(“msg”); String choice = request.getParameter(“choice”); params.put(“msg”, choice+“-”+user+“-”+reviewMessage); taskSplete(taskId, params); 待第一个的审批工作完成后,流程引擎会产生 Task 事件,
11、经由并行网关处理后,系统将生成“人力专员确认“的 UserTask 任务和”自动备案“的 ServiceTask 任务,其中 ServiceTask 任务将由系统自动执行,” 人力专员确认“ 任务依然通过 Step5、6、7 完成,待这两个任务都完成后,两条路由分支由”合并“路由流转到”结束“节点,至此,流程结束。通过以上 API 的应用分析,Activiti5 API 构成清晰,针对性更强,不同的功能由相应的服务接口完成,访问接口更友好。总 结BPMN2.0 是一个工作流业界标准,规范了大型厂商和开源工作流产品的实现,Activiti5 实现了该标准的大部分图元定义和执行语义解释,功能强大,
12、Activiti5 可以与 IBM、Oracle 等大型商用工作流产品流程引擎节点的核心功能媲美,并且为了简化应用、扩充原有功能,Activiti5 又自定义了 6 个扩展元素和 15 个扩展属性,这些元素和属性能够与 BPMN 规范相互组合可以实现更多、更实用的业务功能。笔者通过技术组成、对 BPMN 规范的覆盖率、API 应用友好性、社区支持度、第三方组件依赖程度以及可扩展性六个方面进行分析和比对,Activiti5 的综合实力较强。对于如何选型符合 BPMN 标准的工作流产品,这是一个仁者见仁智者见智的问题,一方面依赖于各个公司对工作流技术方面的历史积累,另一方面也要针对具体项目具体情况区别对待。但如果对于一个全新的项目或对 jBPM3、4 设计理念认同的公司,不妨考虑 Activiti5。关 于 作 者晁扬扬,曾供职于某船舶企业国家级技术中心,有 8 年 PLM 及企业信息化系统的设计与开发经历,擅长信息化集成及J2EE 系统设计与开发,出于对技术的热忱和进一步的拓展空间,现加入远光软件股份有限公司,从事平台设计开发工作,最近专注于脚本语言、流程引擎及相关技术的研究。尽人事知天命,相信天道酬勤,热爱开源软件,热爱户外运动。附: bpmn20.xml感谢王翔对本文的审校。