Activiti7工作流學習筆記一 流程定義

Activiti7工作流學習筆記一

工作流(Workflow),就是“業務過程的部分或整體在計算機應用環境下的自動化”,它主要解決的是“使在多個參與者之間按照某種預定義的規則傳遞文檔、信息或任務的過程自動進行,從而實現某個預期的業務目標,或者促使此目標的實現”。

工作流管理系統(Workflow Management System, WfMS)是一個軟件系統,它完成工作量的定義和管理,並按照在系統中預先定義好的工作流規則進行工作流實例的執行。工作流管理系統不是企業的業務系統,而是爲企業的業務系統的運行提供了一個軟件的支撐環境。

工作流管理聯盟(WfMC,Workflow Management Coalition)給出的關於工作流管理系統的定義是:工作流管理系統是一個軟件系統,它通過執行經過計算的流程定義去支持一批專門設定的業務流程。工作流管理系統被用來定義、管理、和執行工作流程。

工作流管理系統的目標:管理工作的流程以確保工作在正確的時間被期望的人員所執行——在自動化進行的業務過程中插入人工的執行和干預。

Activiti原理分析

在這裏插入圖片描述

使用方式

  1. 定義工作流
    使用eclipse插件完成,leaveProcess.bpmn(計算機進行流程的執行與信息的傳遞使用);leaveProcess.png用戶使用,查看流程的進度
    使用https://demo.bpmn.io/,官方推薦
  2. 執行和管理工作流
    調用Activiti的API

1. 流程部署

  1. 創建processEngine對象
  2. 得到repositoryService實例
  3. 進行部署
  4. 輸出部署的一些信息

表說明

表名 作用
act_re_deployment 流程定義部署表,記錄流程部署信息
act_re_procdef 流程定義表,記錄流程定義信息
act_ge_bytearray 資源表

說明:
act_re_deploymentact_re_procdef 一對多關係

  • 一次部署在流程部署表生成一條記錄,但一次部署可以部署多個流程定義
  • 每個流程定義在流程定義表生成一條記錄
  • 每一個流程定義在act_ge_bytearray會存在兩個資源記錄,bpmnpng

建議:一次部署一個流程,這樣部署表和流程定義表是一對一有關係,方便讀取流程部署及流程定義信息。


/**
 * com.lxf.activiti
 * 流程定義的部署
 * act_re_deployment  部署信息
 * act_re_procdef     流程定義的一些信息
 * act_ge_bytearray   流程定義的bpmn文件及png文件
 * @author lxf
 * @version 1.0
 * @date 2020/4/23 21:20
 */
public class ActivitiDeployment {

//  流程定義部署
  public static void main(String[] args) {
//    1.創建processEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//    2.得到repositoryService實例
    RepositoryService repositoryService = processEngine.getRepositoryService();
//    3.進行部署
    DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
        .addClasspathResource("diagrams/holiday1.bpmn")
        .addClasspathResource("diagrams/holiday.png")
        .name("請假流程申請單");
    Deployment deployment = deploymentBuilder.deploy();
//    4.輸出部署的一些信息
    System.out.println(deployment.getName());
    System.out.println(deployment.getId());
  }

  /**
   * 壓縮形式部署
   * 把bpmn,png文件製成zip類型的壓縮包
   */
  public void deploymentZip(){
    //1.創建ProcessEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到RepositoryService實例
    RepositoryService repositoryService = processEngine.getRepositoryService();

    //3.轉化出ZipInputStream流對象
    InputStream is = ActivitiDeployment.class.getClassLoader().getResourceAsStream("diagrams/holidayBPMN.zip");

    //將 inputstream流轉化爲ZipInputStream流
    ZipInputStream zipInputStream = new ZipInputStream(is);

    //3.進行部署
    Deployment deployment = repositoryService.createDeployment()
        .addZipInputStream(zipInputStream)
        .name("請假申請單流程")
        .deploy();

    //4.輸出部署的一些信息
    System.out.println(deployment.getName());
    System.out.println(deployment.getId());
  }

}

2. 啓動流程實例

  1. 流程定義bpmn文件
  2. 流程部署 activiti的三張表
  3. 流程實例
    流程定義類似Java中的一個類
    流程實例類似 Java中的一個實例(對象),一個流程定義可以對應多個流程實例
    在這裏插入圖片描述

表說明

表名 作用
act_hi_actinst 已完成的活動信息
act_hi_identitylink 參與者信息
act_hi_procinst 流程實例
act_hi_taskinst 任務實例
act_ru_execution 執行表
act_ru_identitylink 參與者信息
act_ru_task 任務
/**
 * 啓動流程實例:
 *     前提是先已經完成流程定義的部署工作
 *
 *     背後影響的表:
 *       act_hi_actinst     已完成的活動信息
 *       act_hi_identitylink   參與者信息
 *       act_hi_procinst   流程實例
 *       act_hi_taskinst   任務實例
 *       act_ru_execution   執行表
 *       act_ru_identitylink   參與者信息
 *       act_ru_task  任務
 */
public class ActivitiStartInstance {

  public static void main(String[] args) {
    //1.得到ProcessEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到RunService對象
    RuntimeService runtimeService = processEngine.getRuntimeService();

    //3.創建流程實例  流程定義的key需要知道 holiday
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");

    //4.輸出實例的相關信息
    //null
    System.out.println("流程部署ID->" + processInstance.getDeploymentId());
    //holiday:1:5004
    System.out.println("流程定義ID->" + processInstance.getProcessDefinitionId());
    //10001
    System.out.println("流程實例ID->" + processInstance.getId());
    //null
    System.out.println("活動ID->" + processInstance.getActivityId());

  }
}

流程部署ID->null
流程定義ID->holiday:1:5004
流程實例ID->10001
活動ID->null

3. 查詢任務列表


/**
 * 查詢當前用戶的任務列表
 */
public class ActivitiTaskQuery {


  public static void main(String[] args) {
    ActivitiTaskQuery taskQuery = new ActivitiTaskQuery();
    taskQuery.taskQuery4ZhangSan();
  }

  /**
   * wangwu完成自己任務列表的查詢
   */
  public void taskQuery4WangWu() {
    //1.得到ProcessEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService對象
    TaskService taskService = processEngine.getTaskService();

    //3.根據流程定義的key,負責人assignee來實現當前用戶的任務列表查詢
    Task task = taskService.createTaskQuery()
        .processDefinitionKey("holiday")
        .taskAssignee("wangwu")
        .singleResult();

    //4.任務列表的展示
    printTaskInfo(task);
  }

  /**
   * lishi完成自己任務列表的查詢
   */
  public void taskQuery4LiShi() {
    //1.得到ProcessEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService對象
    TaskService taskService = processEngine.getTaskService();

    //3.根據流程定義的key,負責人assignee來實現當前用戶的任務列表查詢
    Task task = taskService.createTaskQuery()
        .processDefinitionKey("holiday")
        .taskAssignee("lishi")
        .singleResult();

    //4.任務列表的展示
    printTaskInfo(task);
  }


  /**
   * zhangsan任務列表的查詢
   */
  public void taskQuery4ZhangSan() {
    //1.得到ProcessEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService對象
    TaskService taskService = processEngine.getTaskService();

    //3.根據流程定義的key,負責人assignee來實現當前用戶的任務列表查詢
    List<Task> taskList = taskService.createTaskQuery()
        .processDefinitionKey("holiday")
        .taskAssignee("zhangsan")
        .list();

    //4.任務列表的展示
    taskList.stream().forEach(this::printTaskInfo);
  }

  /**
   * 輸出任務信息
   */
  public void printTaskInfo(Task task) {
    System.out.println("流程實例ID:" + task.getProcessInstanceId());
    System.out.println("任務ID:" + task.getId());
    System.out.println("任務負責人:" + task.getAssignee());
    System.out.println("任務名稱:" + task.getName());
  }
}

結果:

流程實例ID:10001
任務ID:10005
任務負責人:zhangsan
任務名稱:填寫請假申請單
流程實例ID:7501
任務ID:7505
任務負責人:zhangsan
任務名稱:填寫請假申請單

4. 處理當前用戶的任務


/**
 * 處理當前用戶的任務 背後操作的表:
 * act_hi_actinst
 * act_hi_identitylink 記錄參與者
 * act_hi_taskinst
 * act_ru_identitylink
 * act_ru_task 當前正要執行的任務,每次從流程圖中載入一個任務,當任務完成後刪除,最終爲空
 */
public class ActivitiCompleteTask {

  public static void main(String[] args) {
    ActivitiCompleteTask completeTask = new ActivitiCompleteTask();
    completeTask.zhangSanComplete();
    completeTask.complete("lishi");
    completeTask.complete("wangwu");
  }

  /**
   * zhangsan完成自己的任務
   */
  public void zhangSanComplete() {
    //1.得到ProcessEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService對象
    TaskService taskService = processEngine.getTaskService();

    //3.處理任務,結合當前用戶任務列表的查詢操作的話,任務ID:10005
    taskService.complete("10005");
  }

  /**
   * 查詢當前用戶的任務並處理掉
   */
  public void complete(String assignee) {
    //1.得到ProcessEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService對象
    TaskService taskService = processEngine.getTaskService();

    //3.查詢當前用戶的任務
    List<Task> taskList = taskService.createTaskQuery()
        .processDefinitionKey("holiday")
        .taskAssignee(assignee)
        .list();
    taskList.stream().forEach(task -> {
      //4.處理任務,結合當前用戶任務列表的查詢操作的話,任務ID:task.getId()
      taskService.complete(task.getId());
      //5.輸出任務的id
      System.out.println(task.getId());
    });
  }
}

流程定義

查看流程定義信息

/**
* 操作一、查詢流程定義信息
*/
public void queryProcessDefinition() {
	 //1.得到ProcessEngine對象
	 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	 //2.創建RepositoryService對象
	 RepositoryService repositoryService = processEngine.getRepositoryService();
	
	 //3.得到ProcessDefinitionQuery對象,可以認爲它就是一個查詢器
	 ProcessDefinitionQuery processDefinitionQuery = repositoryService
	     .createProcessDefinitionQuery();
	
	 //4.設置條件,並查詢出當前的所有流程定義   查詢條件:流程定義的key=holiday
	 //orderByProcessDefinitionVersion() 設置排序方式,根據流程定義的版本號進行排序
	 List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("holiday")
	     .orderByProcessDefinitionVersion()
	     .desc().list();
	 //5.輸出流程定義信息
	 list.forEach(this::printProcessDefinitionInfo);
}


  /**
   * 輸出流程定義信息
   */
  public void printProcessDefinitionInfo(ProcessDefinition processDefinition) {
    System.out.println("流程定義ID:" + processDefinition.getId());
    System.out.println("流程定義名稱:" + processDefinition.getName());
    System.out.println("流程定義的Key:" + processDefinition.getKey());
    System.out.println("流程定義的版本號:" + processDefinition.getVersion());
    System.out.println("流程部署的ID:" + processDefinition.getDeploymentId());
  }

輸出

流程定義ID:holiday:1:5004
流程定義名稱:請假流程
流程定義的Key:holiday
流程定義的版本號:1
流程部署的ID:5001

刪除流程定義信息

/**
   * 刪除流程定義信息
   * 背後影響的表(與流程部署用到的一致):
   * act_ge_bytearray
   * act_re_deployment
   * act_re_procdef
   * 注意事項:
   *     1.當我們正在執行的這一套流程沒有完全審批結束的時候,此時如果要刪除流程定義信息就會失敗
   *     2.如果公司層面要強制刪除,可以使用repositoryService.deleteDeployment("1",true);
   *       參數true代表級聯刪除,此時就會先刪除沒有完成的流程結點,最後就可以刪除流程定義信息
   *       false的值代表不級聯
   * @param repositoryService
   * @param deployId
   */
  public void deleteDeployment(RepositoryService repositoryService,String deployId){
    //6.執行刪除流程定義  參數代表流程部署的id
    repositoryService.deleteDeployment(deployId);
  }

流程定義資源查詢

需求:

  1. Activitiact_ge_bytearray表中讀取兩個資源文件
  2. 將兩個資源文件保存到路徑: d:\resources

技術方案:
1.第一種方式使用actviti的api來實現
2.第二種方式:其實就是原理層面,可以使用jdbc的對blob類型,clob類型數據的讀取,並保存
IO流轉換,最好commons-io.jar包可以輕鬆解決IO操作

真實應用場景:用戶想查看這個請假流程具體有哪些步驟要走?

public void queryBpmnFile() throws IOException {
        //1.得到ProcessEngine對象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2.得到RepositoryService對象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3.得到查詢器:ProcessDefinitionQuery對象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

        //4.設置查詢條件
        processDefinitionQuery.processDefinitionKey("holiday");//參數是流程定義的key

        //5.執行查詢操作,查詢出想要的流程定義
        ProcessDefinition processDefinition = processDefinitionQuery.singleResult();

        //6.通過流程定義信息,得到部署ID
        String deploymentId = processDefinition.getDeploymentId();

        //7.通過repositoryService的方法,實現讀取圖片信息及bpmn文件信息(輸入流)
        //getResourceAsStream()方法的參數說明:第一個參數部署id,第二個參數代表資源名稱
        //processDefinition.getDiagramResourceName() 代表獲取png圖片資源的名稱
        //processDefinition.getResourceName()代表獲取bpmn文件的名稱
        InputStream pngIs = repositoryService
            .getResourceAsStream(deploymentId,processDefinition.getDiagramResourceName());
        InputStream bpmnIs = repositoryService
            .getResourceAsStream(deploymentId,processDefinition.getResourceName());

        //8.構建出OutputStream流
        OutputStream pngOs =
            new FileOutputStream("G:\\Activiti7開發計劃\\Activiti7-day03\\資料\\"+processDefinition.getDiagramResourceName());

        OutputStream bpmnOs =
            new FileOutputStream("G:\\Activiti7開發計劃\\Activiti7-day03\\資料\\"+processDefinition.getResourceName());

        //9.輸入流,輸出流的轉換  commons-io-xx.jar中的方法
        IOUtils.copy(pngIs,pngOs);
        IOUtils.copy(bpmnIs,bpmnOs);
        //10.關閉流
        pngOs.close();
        bpmnOs.close();
        pngIs.close();
        bpmnIs.close();
    }

歷史數據的查看


/**
 * com.lxf.activiti.ProcessDefinition
 * 歷史數據的查看
 * @author lxf
 * @version 1.0
 * @date 2020/4/25 19:30
 */
public class HistoryQuery {
  public static void main(String[] args) throws IOException {
    //1.得到ProcessEngine對象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到HistoryService
    HistoryService historyService = processEngine.getHistoryService();

    //3.得到HistoricActivitiInstanceQuery對象
    HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
//設置流程實例的id
    historicActivityInstanceQuery.processInstanceId("2501");

    //4.執行查詢
    List<HistoricActivityInstance> list = historicActivityInstanceQuery
        //排序StartTime
        .orderByHistoricActivityInstanceStartTime().asc().list();

    //5.遍歷查詢結果
    list.forEach(instance->{
      System.out.println(instance.getActivityId());
      System.out.println(instance.getActivityName());
      System.out.println(instance.getProcessDefinitionId());
      System.out.println(instance.getProcessInstanceId());
      System.out.println("=============================");
    });
  }
}

IDEA在快捷鍵

作用
Alt+ Insert IDEA maven項目pom文件插入依賴快捷鍵
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章