activiti我的學習總結

一、關於Activiti

初學activiti我關心的它是什麼東西、有什麼功能、怎麼實現?
先來看一張流程圖感覺一下:java

clipboard.png

  • activiti是一個業務流程管理引擎,它的流程圖大概就像是列車的軌道,而所要執行的對象像是一輛自動運行的列車,只要列車啓動,它就能沿着軌道一直走到終點,而其中的節點就像是列車到達終點途中所要通過的火車站,它會告訴火車下一站是哪裏,而後火車就往指定的下一站駛去,直到終點,流程結束。mysql

  • 如上所描述,最主要的功能就是實現了代碼的自動按流程執行spring

  • 關於怎麼實現,既然這是一個框架,天然就是引進jar包,畫流程圖,而後實現該框架提供的接口來作咱們想要作的事情。sql

二、Activiti數據庫的理解

activiti在每一個節點都能知道下一個節點是什麼,以及當前任務是什麼,那勢必會有存儲流程的各類信息的表。事實也確實如此,activiti能夠配置數據庫,其中存儲了流程運行時的相關信息。在初學Activiti之時,瞭解activiti全部的數據庫表的含義對理解activiti工做機制是有很大幫助的,activiti總共涉及的表格總共有23個:數據庫

clipboard.png

act_ge_*:general通用數據,用於存放數據。
act_re_*:reposity相似於倉庫,存放流程定義文件和流程圖片文件,好比一個流程部署以後能夠在act_re_deployment表中看到。
act_ru_*:run服務運行時候的數據,當一個流程啓動以後當前的活動任務能夠在act_ru_task表格中查看 ,以及流程中全部的變量都保存在act_ru_variable表格當中。express


原本想寫一系列完整的Activiti的學習筆記的,可是學完以後發現工做量着實不小,自身學的也不夠深,何況網上大有牛人有相似的學習筆記,因此此文權當是我的學習activiti的過程當中填坑記錄,僅供參考;

三、運行環境搭建,最簡單的運行環境(學習中用到了Junit 4用來測試很好用。),eclipse+jar包+mysql,配置文件,由於我這裏沒有與Spring整合,因此配置文件就一個activiti.cfg.xml放在class_path下面就行了。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- 
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
        //數據庫配置
        configuration.setJdbcDriver("com.mysql.jdbc.Driver");
        configuration.setJdbcUrl("jdbc:mysql://localhost:3306/itcast0621activiti?useUnicode=true&amp;characterEncoding=utf8");
        configuration.setJdbcUsername("root");
        configuration.setJdbcPassword("root");
        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
     -->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/lewinactiviti?useUnicode=true&amp;characterEncoding=utf8"></property>
        <property name="jdbcUsername" value="root"></property>
        <property name="jdbcPassword" value="123456"></property>
        <!-- 
            建立表的策略
         -->
        <property name="databaseSchemaUpdate" value="true"></property>
    </bean>
</beans>

四、下載畫流程工具activiti-app.war

從官網下載war包(登陸用戶密碼:admin test),找到activiti-app.war放進tomcat,啓動以後本身畫一個流程圖,用於下面的測試
war包下載:https://www.activiti.org/down...
版本6.xx的相關文檔都在這裏:https://www.activiti.org/docs
版本5.xx的官網好像再也不維護了
[畫圖工具]apache

clipboard.png

五、開始實現Activiti的一些api,並查看錶格中的變化

package com.lewin.activiti.taskListener;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.io.FileUtils;
import org.junit.Test;

public class DepolyTest {
    @Test
    public void run(){
        //獲取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        Deployment deployment = processEngine.getRepositoryService()
                .createDeployment()
                //.addClasspathResource("taskListener.bpmn20.xml")
                .addClasspathResource("UserExecuteTask.bpmn20.xml")
                .deploy();
        String piid = deployment.getId();
        System.out.println("processDefinitionId:"+piid);
        //String processKey = "lewin";
        String processKey = "UserExecuteTask";
        ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey(processKey);
        System.out.println(pi.getId());
    }
    
    /**
     * 根據流程定義裏的id啓動流程實例
     */
    public void startInstance(){
        String processInstanceKey = "lewin";
        //「lewin」即對應着流程定義中的id值
        ProcessInstance pi = ProcessEngines.getDefaultProcessEngine()
                .getRuntimeService()
                .startProcessInstanceByKey(processInstanceKey);
        System.out.println("started processInstance id is:"+processInstanceKey+"; pi.id is:"+pi.getId());
    }
    
    /*
     * 從class_path中部署流程實例
     */
    @Test
    public void deploymentProcessDefinition_classpath(){
        //獲取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        Deployment deployment = processEngine.getRepositoryService()//獲取倉庫服務
                        .createDeployment()//建立部署實例
                        .name("deploymentName")//設置將要部署的流程實例的名稱
                        .addClasspathResource("taskListener.bpmn20.xml")//資源文件:默認路徑在class_path下面
                      //.addClasspathResource("diagrams/HelloWorld.png")
                        .deploy();//部署
        System.out.println("id:"+deployment.getId());
        System.out.println("name:"+deployment.getName());
        
    }
    
    /*
     * 查詢定義了的流程
     * 查詢內容來自act_re_deployment
     */
    @Test
    public void findProcessDefinition(){
        //獲取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        List<ProcessDefinition> list = processEngine.getRepositoryService()
                        .createProcessDefinitionQuery()
                        
                        //.deploymentId(deploymentId)
                        //.processDefinitionId(processDefinitionId)
                        //.processDefinitionKey(processDefinitionKey)
                        //.processDefinitionNameLike(processDefinitionNameLike)
                        
                       
                        .orderByProcessDefinitionVersion().asc()
                        //.orderByProcessDefinitionName().desc()
                        
                        .list();
                        //.singleResult();
                        //.count();
                        //.listPage(firstResult, maxResults)
        
        if(list != null && list.size()>0){
            for(ProcessDefinition processDefinition:list){
                System.out.println("ID:"+processDefinition.getId());
                System.out.println("NAME:"+processDefinition.getName());
                System.out.println("KEY:"+processDefinition.getKey());
                System.out.println("VERSION:"+processDefinition.getVersion());
                System.out.println("resourceName:"+processDefinition.getResourceName());
                System.out.println("圖片名字:"+processDefinition.getDiagramResourceName());
                System.out.println("部署的流程id:"+processDefinition.getDeploymentId());
                System.out.println("################################");
            }
        }
        
    }
    
    /*
     * 刪除流程定義
     */
    @Test
    public void deleteProcessDefinition(){
        //獲取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //流程定義id
        String deploymentId = "2201";
        
        processEngine.getRepositoryService()
                        .deleteDeployment(deploymentId, true);
        
        System.out.println("刪除成功!");
    }
    
    /*
     * 查看流程定義圖並下載到本地
     */
    @Test
    public void viewPic() throws IOException{
        //獲取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        /**流程部署id*/
        String deploymentId = "201";
        //根據id獲取存儲在act_re_deployment表裏面的靜態資源,裏面就有圖片
        List<String> list = processEngine.getRepositoryService()//
                        .getDeploymentResourceNames(deploymentId);
        //獲取名字
        String resourceName = "";
        if(list!=null && list.size()>0){
            for(String name:list){
                if(name.indexOf(".png")>=0){
                    resourceName = name;
                }
            }
        }
        
        
        //獲取圖片資源
        InputStream in = processEngine.getRepositoryService()//
                        .getResourceAsStream(deploymentId, resourceName);
        
        //新建文件
        File file = new File("D:/"+resourceName);
        //文件複製
        FileUtils.copyInputStreamToFile(in, file);
    }
    
    /*
     * 刪除路程定義根據定義中的名字
     */
    @Test
    public void deleteProcessDefinitionByKey(){
        //獲取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //流程定義文件中的名字,若是相同名字有多個默認使用版本最高的那個
        String processDefinitionKey = "UserExecuteTask";
        List<ProcessDefinition> list = processEngine.getRepositoryService()
                        .createProcessDefinitionQuery()
                        .processDefinitionKey(processDefinitionKey)
                        .list();
        //刪除全部名字爲UserExecuteTask的流程定義
        if(list!=null && list.size()>0){
            for(ProcessDefinition pd:list){
                //獲取ID
                String deploymentId = pd.getDeploymentId();
                processEngine.getRepositoryService()
                                .deleteDeployment(deploymentId);
            }
        }
    }
    
    /**
     * 查詢流程狀態
     */
    @Test
    public void queryInstanceState(){
        //流程id
        String instanceId = "1309";
        //任務id
        String taskId = "1312";
        //獲取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //經過流程id查詢狀態
        ProcessInstance pi = processEngine.getRuntimeService()
                .createProcessInstanceQuery()//建立查詢
                .processInstanceId(instanceId)//根據id
                .singleResult();//獲取狀態
        if(pi!=null){
            System.out.println("id爲"+instanceId+"的流程正在進行中......");
            //完成當前節點
            processEngine.getTaskService().complete(taskId);
        }else{
            System.out.println("id爲"+instanceId+"的流程已經完成!");
        }
    }
    
    /**
     * 查詢流程執行對象
     */
    @Test
    public void queryExecution(){
        //查詢執行對象
        String exe = "User Task";
        //獲取流程實例
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //查詢
        Execution e1 = processEngine.getRuntimeService()
                .createExecutionQuery()
                .processInstanceId("1509")
                .activityId(exe)
                .singleResult();
        if(e1!=null){
            System.out.println("e1!=null");
        }else{
            System.out.println("e1==null");
        }
    }
    
    /**
     * 根據用戶查詢任務
     */
    @Test
    public void queryUserTask(){
        
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // Fetch all tasks for the management group
        TaskService taskService = processEngine.getTaskService();
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
        for (Task task : tasks) {
          System.out.println("Task available: " + task.getName());
        }
    }
    
    
}

六、例子1:只有用戶任務和並行網關的運行

clipboard.png

UserExecuteTask.bpmn20.xml文件:api

<?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="daling">  
  <process id="UserExecuteTask" name="UserExecuteTask"> 
      <!-- 開始和結束監聽事件 -->
     <extensionElements>  
      <activiti:executionListener event="start" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>  
      <activiti:executionListener event="end" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>  
    </extensionElements> 
    <!-- 開始和結束監聽事件結束 --> 
    <startEvent id="startevent1" name="Start"></startEvent>  
    <parallelGateway id="parallelgateway1" name="start"></parallelGateway>  
    <userTask id="servicetask1" name="servicetask1" >  
       <extensionElements>  
          <activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.DeveloperManagerUserTaskListener"/>  
       </extensionElements>  
    </userTask>  
    <userTask id="servicetask2" name="servicetask2">  
       <extensionElements>  
          <activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.ProductManagerUserTaskListener"/>  
       </extensionElements>  
    </userTask>  
    <userTask id="servicetask3" name="servicetask3" >  
          <extensionElements>  
          <activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.TeamLeaderUserTaskListener"/>  
       </extensionElements>  
    </userTask>  
    <parallelGateway id="parallelgateway2" name="First Join"></parallelGateway>  
    <userTask id="servicetask4" name="servicetask4" >  
       <extensionElements>  
          <activiti:taskListener event="complete" class="com.lewin.activiti.UserExecute.ProductBossUserTaskListener"/>  
       </extensionElements>  
    </userTask>  
    <parallelGateway id="parallelgateway3" name="parallelgateway3"></parallelGateway>  
    <userTask id="servicetask5" name="servicetask5" >  
        <extensionElements>  
           <activiti:taskListener event="complete"  class="com.lewin.activiti.UserExecute.HumanResouceUserTaskListener"/>  
        </extensionElements>  
    </userTask>  
    <endEvent id="endevent1" name="End"></endEvent>  
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="parallelgateway1"></sequenceFlow>  
    <sequenceFlow id="flow2" name="" sourceRef="parallelgateway1" targetRef="servicetask1"></sequenceFlow>  
    <sequenceFlow id="flow3" name="" sourceRef="parallelgateway1" targetRef="servicetask2"></sequenceFlow>  
    <sequenceFlow id="flow4" name="" sourceRef="parallelgateway1" targetRef="servicetask3"></sequenceFlow>  
    <sequenceFlow id="flow5" name="" sourceRef="servicetask1" targetRef="parallelgateway2"></sequenceFlow>  
    <sequenceFlow id="flow6" name="" sourceRef="servicetask2" targetRef="parallelgateway2"></sequenceFlow>  
    <sequenceFlow id="flow7" name="" sourceRef="servicetask3" targetRef="parallelgateway3"></sequenceFlow>  
    <sequenceFlow id="flow8" name="" sourceRef="parallelgateway2" targetRef="servicetask4"></sequenceFlow>  
    <sequenceFlow id="flow9" name="" sourceRef="servicetask4" targetRef="parallelgateway3"></sequenceFlow>  
    <sequenceFlow id="flow10" name="" sourceRef="parallelgateway3" targetRef="servicetask5"></sequenceFlow>  
    <sequenceFlow id="flow11" name="" sourceRef="servicetask5" targetRef="endevent1"></sequenceFlow>  
  </process>  
</definitions>

測試代碼:
/**tomcat

* 對應UserExecuteTask.bpmn20.xml
     * 這是一個用戶任務,因此流程徹底執行須要用戶的參與
     * 獲取全部任務
     * 
     */
    @Test
    public void getAllTasks(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //獲取倉庫實例
        Deployment deployment = processEngine.getRepositoryService()
                .createDeployment()
                .addClasspathResource("UserExecuteTask.bpmn20.xml")
                .deploy();
        //啓動流程實例
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey("UserExecuteTask");
        System.out.println("pi.id:"+pi.getId());
        
        //第一輪(流程啓動以後自動進入下一級節點,
        //下一級節點爲並行的三個任務,獲取該三個任務依次按定義文件中順序完成) 
        TaskService taskService = processEngine.getTaskService();
        TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc();
        List<Task> tasks = query.list();
        //循環打印tasks的信息
        for(Task task : tasks){
            //執行任務  ,完成任務
            taskService.complete(task.getId());  
            System.out.println("name ="+task.getName()); 
            System.out.println(tasks.size());
        }
            
        //第二輪查詢任務:上一輪三個任務依次完成以後開始進入下一輪,第二級節點  
        tasks = query.list();
        //循環打印tasks的信息
          for(Task task : tasks){
              //執行任務  ,完成任務
              taskService.complete(task.getId());  
              System.out.println("name ="+task.getName()); 
              System.out.println(tasks.size());
          }
          
        //第三輪查詢任務:上一輪一個任務完成以後,開始進入下一級節點,
          //即最後的人事部門審批  
        tasks = query.list();
        //循環打印tasks的信息
          for(Task task : tasks){
              //執行任務  ,完成任務
              taskService.complete(task.getId());  
              System.out.println("name ="+task.getName()); 
              System.out.println(tasks.size());
          }
    }

運行結果:app

clipboard.png

七、例子2:只有系統任務和並行網關的運行

clipboard.png

AutoUserExecuteTask.bpmn20.xml文件:

<?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: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="AutoUserExecuteTask" name="AutoUserExecuteTask"> 
     <!-- 開始和結束監聽事件 -->
     <extensionElements>  
      <activiti:executionListener event="start" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>  
      <activiti:executionListener event="end" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>  
    </extensionElements> 
    <!-- 開始和結束監聽事件結束 -->
    <startEvent id="startevent1" name="Start"></startEvent>  
    <parallelGateway id="parallelgateway1" name="多種請假方式"></parallelGateway>  
    <serviceTask id="servicetask1" name="項目經理贊成" activiti:class="com.lewin.activiti.UserExecuteService.DeveloperManagerServiceTask"></serviceTask>  
    <serviceTask id="servicetask2" name="產品經理贊成" activiti:class="com.lewin.activiti.UserExecuteService.ProductManagerServiceTask"></serviceTask>  
    <serviceTask id="servicetask3" name="項目組長贊成" activiti:class="com.lewin.activiti.UserExecuteService.TeamLeaderServiceTask"></serviceTask>  
    <parallelGateway id="parallelgateway2" name="First Join"></parallelGateway>  
    <serviceTask id="servicetask4" name="項目總監贊成" activiti:class="com.lewin.activiti.UserExecuteService.ProductBossServiceTask"></serviceTask>  
    <parallelGateway id="parallelgateway3" name="人事判斷"></parallelGateway>  
    <serviceTask id="servicetask5" name="人事部門贊成" activiti:class="com.lewin.activiti.UserExecuteService.HumanResouceServiceTask"></serviceTask>  
    <endEvent id="endevent1" name="End"></endEvent>  
    <sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="parallelgateway1"></sequenceFlow>  
    <sequenceFlow id="flow2" name="" sourceRef="parallelgateway1" targetRef="servicetask1"></sequenceFlow>  
    <sequenceFlow id="flow3" name="" sourceRef="parallelgateway1" targetRef="servicetask2"></sequenceFlow>  
    <sequenceFlow id="flow4" name="" sourceRef="parallelgateway1" targetRef="servicetask3"></sequenceFlow>  
    <sequenceFlow id="flow5" name="" sourceRef="servicetask1" targetRef="parallelgateway2"></sequenceFlow>  
    <sequenceFlow id="flow6" name="" sourceRef="servicetask2" targetRef="parallelgateway2"></sequenceFlow>  
    <sequenceFlow id="flow7" name="" sourceRef="servicetask3" targetRef="parallelgateway3"></sequenceFlow>  
    <sequenceFlow id="flow8" name="" sourceRef="parallelgateway2" targetRef="servicetask4"></sequenceFlow>  
    <sequenceFlow id="flow9" name="" sourceRef="servicetask4" targetRef="parallelgateway3"></sequenceFlow>  
    <sequenceFlow id="flow10" name="" sourceRef="parallelgateway3" targetRef="servicetask5"></sequenceFlow>  
    <sequenceFlow id="flow11" name="" sourceRef="servicetask5" targetRef="endevent1"></sequenceFlow>  
  </process>  
    
    
</definitions>

測試代碼:

/**
     * 對應UserExecuteTask.bpmn20.xml
     * 這是一個自動任務(不包含用戶任務),因此流程徹底執行不須要用戶的參與
     * 只須要啓動實例,流程會自動按流程走完
     * 獲取全部任務
     * 
     */
    @Test
    public void autoRun(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //獲取倉庫實例
        Deployment deployment = processEngine.getRepositoryService()
                .createDeployment()
                .addClasspathResource("AutoUserExecuteTask.bpmn20.xml")
                .deploy();
        //啓動流程實例
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey("AutoUserExecuteTask");
        System.out.println("pi.id:"+pi.getId());
    }

運行結果:

![圖片上傳中...]

八、例子3:只有用戶任務和排他網關的運行

clipboard.png

ExclusiveGatawayDemo.bpmn20.xml文件:

<?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/processdef">
  <process id="ExclusiveGatawayDemo" name="ExclusiveGatawayDemo" isExecutable="true">
    <documentation>ExclusiveGatawayDemo</documentation>
    <extensionElements>
      <activiti:executionListener event="start" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>
      <activiti:executionListener event="end" class="com.lewin.activiti.taskListener.MyExecutionListener"></activiti:executionListener>
    </extensionElements>
    <startEvent id="start" name="start"></startEvent>
    <userTask id="userTask1" name="userTask1">
      <extensionElements>
        <activiti:taskListener event="create" class="com.lewin.activiti.UserExecute.DeveloperManagerUserTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-8BBA58D7-2F3B-45BD-B5EE-3924FC60D227" sourceRef="start" targetRef="userTask1"></sequenceFlow>
    <exclusiveGateway id="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19"></exclusiveGateway>
    <sequenceFlow id="sid-E0C94A44-BBEE-4110-A4B6-CE3650AF5483" sourceRef="userTask1" targetRef="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19"></sequenceFlow>
    <userTask id="userTask2" name="userTask2">
      <extensionElements>
        <activiti:taskListener event="create" class="com.lewin.activiti.UserExecute.ProductManagerUserTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <userTask id="userTask3" name="userTask3">
      <extensionElements>
        <activiti:taskListener event="create" class="com.lewin.activiti.UserExecute.TeamLeaderUserTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>
    <endEvent id="end" name="end"></endEvent>
    <sequenceFlow id="sid-2C04111C-D70E-414A-88C4-980B52F9D5AA" sourceRef="userTask2" targetRef="end"></sequenceFlow>
    <sequenceFlow id="sid-8A2D5D75-9ED6-441D-8E94-82ADCDC596EC" sourceRef="userTask3" targetRef="end"></sequenceFlow>
    <sequenceFlow id="sid-37A2D2A5-FA8D-43D7-8F44-3DD5739C9A43" sourceRef="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19" targetRef="userTask2">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${myCondition=="userTask2"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-98459295-57D8-4E1D-9AE5-F5DCE1B99B41" sourceRef="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19" targetRef="userTask3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${myCondition=="userTask3"}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_ExclusiveGatawayDemo">
    <bpmndi:BPMNPlane bpmnElement="ExclusiveGatawayDemo" id="BPMNPlane_ExclusiveGatawayDemo">
      <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
        <omgdc:Bounds height="30.0" width="30.0" x="105.0" y="119.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="userTask1" id="BPMNShape_userTask1">
        <omgdc:Bounds height="80.0" width="100.0" x="270.0" y="94.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19" id="BPMNShape_sid-B1F674E4-D27C-4682-BDA6-E2EE96D4EF19">
        <omgdc:Bounds height="40.0" width="40.0" x="500.5" y="114.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="userTask2" id="BPMNShape_userTask2">
        <omgdc:Bounds height="80.0" width="100.0" x="720.0" y="94.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="userTask3" id="BPMNShape_userTask3">
        <omgdc:Bounds height="80.0" width="100.0" x="720.0" y="255.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
        <omgdc:Bounds height="28.0" width="28.0" x="999.5" y="120.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-8BBA58D7-2F3B-45BD-B5EE-3924FC60D227" id="BPMNEdge_sid-8BBA58D7-2F3B-45BD-B5EE-3924FC60D227">
        <omgdi:waypoint x="135.0" y="134.0"></omgdi:waypoint>
        <omgdi:waypoint x="270.0" y="134.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-E0C94A44-BBEE-4110-A4B6-CE3650AF5483" id="BPMNEdge_sid-E0C94A44-BBEE-4110-A4B6-CE3650AF5483">
        <omgdi:waypoint x="370.0" y="134.0"></omgdi:waypoint>
        <omgdi:waypoint x="500.5" y="134.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-98459295-57D8-4E1D-9AE5-F5DCE1B99B41" id="BPMNEdge_sid-98459295-57D8-4E1D-9AE5-F5DCE1B99B41">
        <omgdi:waypoint x="521.0" y="153.5"></omgdi:waypoint>
        <omgdi:waypoint x="521.0" y="295.0"></omgdi:waypoint>
        <omgdi:waypoint x="720.0" y="295.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-37A2D2A5-FA8D-43D7-8F44-3DD5739C9A43" id="BPMNEdge_sid-37A2D2A5-FA8D-43D7-8F44-3DD5739C9A43">
        <omgdi:waypoint x="540.0382293762575" y="134.46177062374247"></omgdi:waypoint>
        <omgdi:waypoint x="720.0" y="134.1004016064257"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-8A2D5D75-9ED6-441D-8E94-82ADCDC596EC" id="BPMNEdge_sid-8A2D5D75-9ED6-441D-8E94-82ADCDC596EC">
        <omgdi:waypoint x="820.0" y="295.0"></omgdi:waypoint>
        <omgdi:waypoint x="1012.5" y="295.0"></omgdi:waypoint>
        <omgdi:waypoint x="1012.5" y="158.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-2C04111C-D70E-414A-88C4-980B52F9D5AA" id="BPMNEdge_sid-2C04111C-D70E-414A-88C4-980B52F9D5AA">
        <omgdi:waypoint x="820.0" y="134.0"></omgdi:waypoint>
        <omgdi:waypoint x="999.5" y="134.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

測試代碼:

/**
     * 對應ExclusiveGatewayDemo.bpmn20.xml
     * 包含排他網關的流程
     * 獲取全部任務
     * 
     */
    @Test
    public void exclusiveGatewayTasks(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //獲取倉庫實例
        Deployment deployment = processEngine.getRepositoryService()
                .createDeployment()
                .name("ExclusiveGatawayDemo_Deploymentname")
                .addClasspathResource("ExclusiveGatawayDemo.bpmn20.xml")
                .deploy();
        //啓動流程實例
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey("ExclusiveGatawayDemo");
        System.out.println("pi.id:"+pi.getId());
        
        //第一輪(流程啓動以後自動進入下一級節點,
        //下一級節點爲並行的三個任務,獲取該三個任務依次按定義文件中順序完成) 
        TaskService taskService = processEngine.getTaskService();
        TaskQuery query = taskService.createTaskQuery().processInstanceId(pi.getId()).orderByTaskName().asc();
        List<Task> tasks = query.list();
        //循環打印tasks的信息
        for(Task task : tasks){
            //執行任務  ,完成任務
            taskService.complete(task.getId());  
            System.out.println("name ="+task.getName()); 
            System.out.println(tasks.size());
        }
        /**
         * userTask1完成,而且設置變量「myCondition」
         * 這裏測試設置的值是"userTask3"
         * 按照定義應該執行userTask3
         * 註釋下面代碼的狀況下,查詢act_ru_task能夠查看到有userTask3任務
         * 不註釋的狀況下,流程完成userTask1和userTask3走完整個流程
         */
            
        //第二輪查詢任務:上一輪三個任務依次完成以後開始進入下一輪,第二級節點  
        tasks = query.list();
        //循環打印tasks的信息
          for(Task task : tasks){
              //執行任務  ,完成任務
              taskService.complete(task.getId());  
              System.out.println("name ="+task.getName()); 
              System.out.println(tasks.size());
          }
          
        //第三輪查詢任務:上一輪一個任務完成以後,開始進入下一級節點,
          //即最後的人事部門審批  
        tasks = query.list();
        //循環打印tasks的信息
          for(Task task : tasks){
              //執行任務  ,完成任務
              taskService.complete(task.getId());  
              System.out.println("name ="+task.getName()); 
              System.out.println(tasks.size());
          }
    }

運行結果:

clipboard.png

字數不夠,代碼來湊,草草結束,細節之處多有遺漏,有一塊兒學習的有問題的能夠私信。強行回顧了一下前兩天的學習歷程。

相關文章
相關標籤/搜索