SpringBoot整合Activiti7使用

漠翊歌發表於2020-11-21

最近做的一個專案中需要實現員工請假的功能,計劃使用activiti來實現請假流程,所以去學習了一下相關的知識。並且完成了一個簡單的請假例項。

Activiti相關

Activiti介紹

Activiti是基於Apache許可的開源BPM平臺,創始人Tom Baeyens原是JBPM架構師,可以理解為與JBPM出自同一祖師爺。它提供了Eclipse外掛,開發可以通過外掛直接繪製業務流程圖。基於Spring,ibatis等框架,並在此之上構建了非常清晰的開發框架。是由Alfresco軟體釋出的業務流程管理(BPM)框架,它是覆蓋了業務流程管理、工作流、服務協作等領域的一個開源的、靈活的、易擴充套件的可執行流程語言框架。 本文基於Activiti7的Activiti Core,基於Spring Boot做簡單學習總結。

Acticiti核心類介紹

ProcessEngine

流程引擎的抽象,可以通過此類獲取需要的所有服務。

Service類

通過ProcessEngine獲取,Activiti將不同生命週期的服務封裝在不同Service中,包括定義、部署、執行。通過服務類可獲取相關生命週期中的服務資訊。

taskService

流程執行過程中,每個任務節點的相關操作介面,如complete,delete,delegate等。

RepositoryService

流程定義和部署相關的儲存服務

RuntimeService

流程執行時相關的服務,如根據流程好啟動流程例項startProcessInstanceByKey。

HistoryService

歷史記錄相關服務介面。

專案搭建

建立SpringBoot專案並且新增maven依賴

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.1.6.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.example</groupId>
   <artifactId>demo</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>demo</name>
   <description>Demo project for Spring Boot</description>

   <properties>
      <java.version>1.8</java.version>
   </properties>

   <dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>

      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-devtools</artifactId>
         <scope>runtime</scope>
         <optional>true</optional>
      </dependency>
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <optional>true</optional>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
      <dependency>
         <groupId>org.activiti</groupId>
         <artifactId>activiti-spring-boot-starter</artifactId>
         <version>7.0.0.Beta2</version>
      </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>

</project>

新增配置檔案

application.yml:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/test2?nullCatalogMeansCurrent=true
    driver-class-name: com.mysql.cj.jdbc.Driver
  devtools:
      restart:
        enabled: true  #設定開啟熱部署
  activiti:
    database-schema-update: true
    history-level: full
    db-history-used: true


debug: true

建立流程圖

在建立流程圖之前首先需要安裝idea支援bpm檔案的外掛

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-XRNZOHIG-1605951841024)([外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-XdduQyP7-1605951841302)(http://114.116.239.228:8090/upload/2020/07/2-16544493610f4a15b2d52a92e60150a5.jpg)]])

安裝成功後在resources目錄下建立processes資料夾並新建holiday.bpmn檔案並且建立流程

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-0r8r0iq9-1605951841026)(3.jpg])

對應xml檔案程式碼如下

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1562573992349" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="myProcess_1" isClosed="false" isExecutable="true" processType="None">
    <startEvent id="_2" name="StartEvent"/>
    <userTask activiti:assignee="${userId}" activiti:exclusive="false" id="_3" name="填寫申請單"/>
    <userTask activiti:assignee="department" activiti:exclusive="true" id="_4" name="稽核"/>
    <endEvent id="_6" name="EndEvent"/>
    <sequenceFlow id="_7" sourceRef="_2" targetRef="_3"/>
    <sequenceFlow id="_8" sourceRef="_3" targetRef="_4"/>
    <sequenceFlow id="_11" sourceRef="_4" targetRef="_6"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="myProcess_1">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <omgdc:Bounds height="32.0" width="32.0" x="225.0" y="175.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <omgdc:Bounds height="55.0" width="85.0" x="435.0" y="175.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
        <omgdc:Bounds height="55.0" width="85.0" x="655.0" y="175.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
        <omgdc:Bounds height="32.0" width="32.0" x="875.0" y="185.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_7" id="BPMNEdge__7" sourceElement="_2" targetElement="_3">
        <omgdi:waypoint x="257.0" y="191.0"/>
        <omgdi:waypoint x="435.0" y="202.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_3" targetElement="_4">
        <omgdi:waypoint x="520.0" y="202.5"/>
        <omgdi:waypoint x="655.0" y="202.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="_4" targetElement="_6">
        <omgdi:waypoint x="740.0" y="202.5"/>
        <omgdi:waypoint x="875.0" y="201.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

執行Application

啟動後檢視資料庫發現springboot 自動讀取了processes下的holiday.bpmn檔案並且部署任務流程到activiti。資料庫中生成了25張工作表。

1.jpg

並且在ACT_GE_BYTEARRAY表中也存在部署的資訊
4.jpg

編寫例項

開啟請假流程

	@Test
	public void start() {
		String instanceKey = "myProcess_1";
		logger.info("開啟請假流程...");
		Map<String, Object> map = new HashMap<String, Object>();
		//在holiday.bpmn中,填寫請假單的任務辦理人為動態傳入的userId,此處模擬一個id
		map.put("userId", "10001");
		ProcessInstance instance = runtimeService.startProcessInstanceByKey(instanceKey, map);
		logger.info("啟動流程例項成功:{}", instance);
		logger.info("流程例項ID:{}", instance.getId());
		logger.info("流程定義ID:{}", instance.getProcessDefinitionId());

	}

執行結果:

5.jpg
執行後成功開啟了一個請假例項並且獲取到id為:adc6a5f0-a2c3-11e9-bb83-00e04c83a7ff。

填寫請假單

通過例項id可以查詢到例項所對應的任務,模擬使用者請假的內容存入map中新增為流程變數。

	@Test
	public void employeeApply() {
		String instanceId = "adc6a5f0-a2c3-11e9-bb83-00e04c83a7ff"; // 任務ID
		String leaveDays = "10"; // 請假天數
		String leaveReason = "回老家結婚"; // 請假原因
		Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
		if (task == null) {
			logger.info("任務ID:{}查詢到任務為空!", instanceId);
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("days", leaveDays);
		map.put("date", new Date());
		map.put("reason", leaveReason);
		taskService.complete(task.getId(), map);
		logger.info("執行【員工申請】環節,流程推動到【上級稽核】環節");
	}

執行結果如下:
6.jpg

流程變數檢視

上級稽核的時候需要檢視到員工所提交的請假相關資訊,可以通過taskService.getVariable的形式來獲取。

	@Test
	public void showTaskVariable (){
		String instanceId = "adc6a5f0-a2c3-11e9-bb83-00e04c83a7ff"; // 任務ID

		Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
		String days = (String) taskService.getVariable(task.getId(), "days");
		Date date = (Date) taskService.getVariable(task.getId(), "date");
		String reason = (String) taskService.getVariable(task.getId(), "reason");
		String userId = (String) taskService.getVariable(task.getId(), "userId");
		System.out.println("請假天數:  " + days);
		System.out.println("請假理由:  " + reason);
		System.out.println("請假人id:  " + userId);
		System.out.println("請假日期:  " + date.toString());
	}

執行結果:

7.jpg

上級審批

上級審批並且新增意見

	@Test
	public void departmentAudit() {
		String instanceId = "adc6a5f0-a2c3-11e9-bb83-00e04c83a7ff"; // 任務ID
		String departmentalOpinion = "早去早回";
		Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("departmentalOpinion", departmentalOpinion);
		taskService.complete(task.getId(), map);
		logger.info("新增審批意見,請假流程結束");
	}

執行結果:

8.jpg

總結

使用Activiti可以方便對流程進行控制。本文只是對簡單的請假流程做了例項,沒有涉及到多工或多分支等情景。對於此類情況以後再做補充。

相關文章