Activiti的簡單應用,應用監聽來實現簡單的業務顆粒與工作流程結合,讓流程帶動業務顆粒執行的過程,此次的流程圖應用多分支結構,並將流程中的判斷值設為參數,由前台傳遞過去。
建立普通java類:
package com.tgb.itoo.activiti.controller;public class xs {public static void SayHello(){System.out.println("88xvshu");}}
建立activiti監聽類:
package com.tgb.itoo.activiti.controller;import org.activiti.engine.delegate.DelegateTask;import org.activiti.engine.delegate.TaskListener;public class xvshuDelegate implements TaskListener{/** * */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateTask delegateTask) {xs.SayHello();}}
類似的Java類和監聽類需要再建立3個
商務程序圖 如圖:
流程變數的屬性設定(jingyuan-${result==flowjingyuan},milaoshi-${result==flowmilaoshi}) 如圖:
最終產生的設定檔 如下:
<?xml version="1.0" encoding="UTF-8"?><definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <process id="myProcess" name="My process" isExecutable="true"> <startEvent id="startevent1" name="Start"></startEvent> <userTask id="xvshu" name="xvshu"> <extensionElements> <activiti:taskListener event="create" class="com.tgb.itoo.activiti.controller.xvshuDelegate"></activiti:taskListener> </extensionElements> </userTask> <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="xvshu"></sequenceFlow> <userTask id="jingyuan" name="jingyuan"> <extensionElements> <activiti:taskListener event="create" class="com.tgb.itoo.activiti.controller.jingyuanDelegate"></activiti:taskListener> </extensionElements> </userTask> <userTask id="usertask1" name="guhaiyan"> <extensionElements> <activiti:taskListener event="create" class="com.tgb.itoo.activiti.controller.guhaiyanDelegate"></activiti:taskListener> </extensionElements> </userTask> <endEvent id="endevent1" name="End"></endEvent> <sequenceFlow id="flow4" sourceRef="usertask1" targetRef="endevent1"></sequenceFlow> <exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway> <sequenceFlow id="flow5" sourceRef="xvshu" targetRef="exclusivegateway1"></sequenceFlow> <sequenceFlow id="flow6" name="jingyuan" sourceRef="exclusivegateway1" targetRef="jingyuan"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${result==flowjingyuan}]]></conditionExpression> </sequenceFlow> <userTask id="usertask2" name="guhaiyan"> <extensionElements> <activiti:taskListener event="create" class="com.tgb.itoo.activiti.controller.guhaiyanDelegate"></activiti:taskListener> </extensionElements> </userTask> <sequenceFlow id="flow13" name="guhaiyan" sourceRef="exclusivegateway1" targetRef="usertask2"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${result==flowhaiyan}]]></conditionExpression> </sequenceFlow> <userTask id="milaoshi" name="milaoshi" activiti:async="true"> <extensionElements> <activiti:taskListener event="create" class="com.tgb.itoo.activiti.controller.milaoshiDelegate"></activiti:taskListener> </extensionElements> </userTask> <sequenceFlow id="flow14" name="milaoshi" sourceRef="exclusivegateway1" targetRef="milaoshi"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${result==flowmilaoshi}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flow15" sourceRef="milaoshi" targetRef="endevent1"></sequenceFlow> <sequenceFlow id="flow16" sourceRef="usertask2" targetRef="endevent1"></sequenceFlow> <sequenceFlow id="flow17" name="guhaiyan" sourceRef="exclusivegateway2" targetRef="usertask1"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${result==flowhaiyan}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flow18" sourceRef="exclusivegateway2" targetRef="endevent1"></sequenceFlow> <exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway> <sequenceFlow id="flow19" sourceRef="jingyuan" targetRef="exclusivegateway2"></sequenceFlow> </process> <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess"> <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess"> <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1"> <omgdc:Bounds height="35.0" width="35.0" x="60.0" y="150.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="xvshu" id="BPMNShape_xvshu"> <omgdc:Bounds height="55.0" width="105.0" x="140.0" y="140.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="jingyuan" id="BPMNShape_jingyuan"> <omgdc:Bounds height="55.0" width="105.0" x="400.0" y="140.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> <omgdc:Bounds height="55.0" width="105.0" x="630.0" y="140.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1"> <omgdc:Bounds height="35.0" width="35.0" x="745.0" y="270.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1"> <omgdc:Bounds height="40.0" width="40.0" x="290.0" y="147.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"> <omgdc:Bounds height="55.0" width="105.0" x="350.0" y="14.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="milaoshi" id="BPMNShape_milaoshi"> <omgdc:Bounds height="55.0" width="105.0" x="258.0" y="260.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2"> <omgdc:Bounds height="40.0" width="40.0" x="539.0" y="147.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> <omgdi:waypoint x="95.0" y="167.0"></omgdi:waypoint> <omgdi:waypoint x="140.0" y="167.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"> <omgdi:waypoint x="735.0" y="167.0"></omgdi:waypoint> <omgdi:waypoint x="762.0" y="173.0"></omgdi:waypoint> <omgdi:waypoint x="762.0" y="270.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5"> <omgdi:waypoint x="245.0" y="167.0"></omgdi:waypoint> <omgdi:waypoint x="290.0" y="167.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"> <omgdi:waypoint x="330.0" y="167.0"></omgdi:waypoint> <omgdi:waypoint x="400.0" y="167.0"></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height="14.0" width="40.0" x="339.0" y="179.0"></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13"> <omgdi:waypoint x="310.0" y="147.0"></omgdi:waypoint> <omgdi:waypoint x="310.0" y="41.0"></omgdi:waypoint> <omgdi:waypoint x="350.0" y="41.0"></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height="14.0" width="44.0" x="310.0" y="91.0"></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14"> <omgdi:waypoint x="310.0" y="187.0"></omgdi:waypoint> <omgdi:waypoint x="310.0" y="260.0"></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height="14.0" width="38.0" x="310.0" y="219.0"></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15"> <omgdi:waypoint x="363.0" y="287.0"></omgdi:waypoint> <omgdi:waypoint x="745.0" y="287.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16"> <omgdi:waypoint x="455.0" y="41.0"></omgdi:waypoint> <omgdi:waypoint x="762.0" y="41.0"></omgdi:waypoint> <omgdi:waypoint x="762.0" y="270.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow17" id="BPMNEdge_flow17"> <omgdi:waypoint x="579.0" y="167.0"></omgdi:waypoint> <omgdi:waypoint x="630.0" y="167.0"></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height="14.0" width="100.0" x="578.0" y="150.0"></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow18" id="BPMNEdge_flow18"> <omgdi:waypoint x="559.0" y="187.0"></omgdi:waypoint> <omgdi:waypoint x="559.0" y="287.0"></omgdi:waypoint> <omgdi:waypoint x="745.0" y="287.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow19" id="BPMNEdge_flow19"> <omgdi:waypoint x="505.0" y="167.0"></omgdi:waypoint> <omgdi:waypoint x="539.0" y="167.0"></omgdi:waypoint> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram></definitions>
啟動流程對應的代碼:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map;import org.activiti.engine.ProcessEngine;import org.activiti.engine.ProcessEngineConfiguration;import org.activiti.engine.RepositoryService;import org.activiti.engine.RuntimeService;import org.activiti.engine.TaskService;import org.activiti.engine.runtime.ProcessInstance;import org.activiti.engine.task.Task;public class NameDemo {private static String readDataFromConsole(String prompt) {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String str = null;try {System.out.print(prompt);str = br.readLine();} catch (IOException e) {e.printStackTrace();}return str;}public static void main(String[] args) {String str = readDataFromConsole("Please input string:");System.out.println("The information from console: " + str);// 建立流程引擎ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();// 串連資料庫的配置processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver");processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/activitiexam?useUnicode=true&characterEncoding=utf8");processEngineConfiguration.setJdbcUsername("root");processEngineConfiguration.setJdbcPassword("root");ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();//使用Spring來管理工作流程引擎的建立/* ProcessEngine processEngine = ProcessEngineConfiguration .createProcessEngineConfigurationFromResource("applicationContext-common.xml") .buildProcessEngine(); */System.out.println(processEngine);// 擷取流程儲存服務元件RepositoryService repositoryService = processEngine.getRepositoryService();// 擷取運行時服務元件RuntimeService runtimeService = processEngine.getRuntimeService();// 擷取流程工作群組件TaskService taskService = processEngine.getTaskService();// 1、部署流程檔案repositoryService.createDeployment().name("MyProcess").addClasspathResource("diagrams/" + str + ".bpmn").deploy();// 2、啟動流程--根據key部署的話是預設找的最新版本ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess");String end="0";//processInstance.getId() != nullwhile (end.equalsIgnoreCase("0")) {//迴圈查詢任務Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();Map<String, Object> variables = new HashMap<String, Object>();if(task==null){end="1";System.out.println("任務已經結束");break;}else{str = readDataFromConsole("Please input result:");String flowjingyuan=readDataFromConsole("Please input flowjingyuan:");String flowhaiyan=readDataFromConsole("Please input flowhaiyan:");String flowmilaoshi=readDataFromConsole("Please input flowmilaoshi:");variables.put("result", str);variables.put("flowjingyuan", flowjingyuan);variables.put("flowhaiyan", flowhaiyan);variables.put("flowmilaoshi", flowmilaoshi);taskService.complete(task.getId(),variables);//完成任務}}}}
執行結果:
總結:
首先解釋一下,現在在用戶端存在的所有暫停其實在真實的開發中均是不存在的,此處只是為了傳遞變數,告訴工作流程如何繼續向下一個結點執行,在真實的開發業務中是不同的人處理不同的任務,每次的查詢只查詢自己的任務,只有本身自己的任務完成後工作流程才會自動向下執行。
解釋一下執行結果:
xvshu結點是在工作流程啟動後立即執行,但是在辦理xvshu結點時需要輸入下一個結點的參數,當輸入的result==flowjingyuan時,則立即執行jingyuan結點,輸出jingyuan88,辦理jingyuan結點時也需要輸入下一個結點的參數,當輸入的內容result==flowhaiyan即立即執行haiyan結點,輸出88guhaiyan,辦理guhaiyan結點時,需要輸入下一個結點的參數,因為haiyan結點的下一個結點為結束,而且沒有條件限制,故輸入任何資訊都會結束。