1. 程式人生 > >spring boot 2.2整合activiti 工作流

spring boot 2.2整合activiti 工作流

pom  檔案新增jar

<!--jwt token-->           <dependency>               <groupId>com.auth0</groupId>               <artifactId>java-jwt</artifactId>               <version>3.3.0</version>           </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->         <dependency>             <groupId>com.fasterxml.jackson.core</groupId>             <artifactId>jackson-core</artifactId>         </dependency>           <!-- https://mvnrepository.com/artifact/org.activiti/activiti-spring -->         <dependency>             <groupId>org.activiti</groupId>             <artifactId>activiti-spring</artifactId>             <version>6.0.0</version>         </dependency>

寫好配置類

import org.activiti.engine.*; import org.activiti.spring.SpringProcessEngineConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager;   import javax.sql.DataSource; import java.io.IOException;   /**  * @author wangsx  * @date Created in 09-10-2018  * @description  */ @Configuration public class ActivitiConfig {       @Bean     public ProcessEngine processEngine(DataSourceTransactionManager transactionManager, DataSource dataSource) throws IOException {         SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration();         //自動部署已有的流程檔案         Resource[] resources = new PathMatchingResourcePatternResolver().getResources(ResourceLoader.CLASSPATH_URL_PREFIX + "processes/*.bpmn");         configuration.setTransactionManager(transactionManager);         configuration.setDataSource(dataSource);         configuration.setDatabaseSchemaUpdate("true");         configuration.setDeploymentResources(resources);         configuration.setDbIdentityUsed(false);         return configuration.buildProcessEngine();     }       @Bean     public RepositoryService repositoryService(ProcessEngine processEngine) {         return processEngine.getRepositoryService();     }       @Bean     public RuntimeService runtimeService(ProcessEngine processEngine) {         return processEngine.getRuntimeService();     }       @Bean     public TaskService taskService(ProcessEngine processEngine) {         return processEngine.getTaskService();     }       @Bean     public HistoryService historyService(ProcessEngine processEngine) {         return processEngine.getHistoryService();     }       @Bean     public ManagementService managementService(ProcessEngine processEngine) {         return processEngine.getManagementService();     }       @Bean     public IdentityService identityService(ProcessEngine processEngine) {         return processEngine.getIdentityService();     }       @Bean     public FormService formService(ProcessEngine processEngine){         return processEngine.getFormService();     } }

springboot 在啟動專案時會自動配置

測試的流程圖

<?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="act_demo_audit">   <process id="act_demo_audit" name="act_demo_audit" isExecutable="true">     <startEvent id="Start" name="開始" activiti:formKey="demo/form"></startEvent>     <userTask id="firstLevelAudit" name="一級審批" activiti:candidateUsers="${firstLevel}"></userTask>     <userTask id="secondLevelAudit" name="二級審批" activiti:candidateUsers="${secondLevel}"></userTask>     <endEvent id="refuse" name="成功"></endEvent>     <sequenceFlow id="flow1" sourceRef="Start" targetRef="firstLevelAudit"></sequenceFlow>     <serviceTask id="acceptService" name="通過時業務處理" activiti:class="com.siemens.pms.act.service.impl.DemoAuditProcessor"></serviceTask>     <sequenceFlow id="flow4" sourceRef="secondLevelAudit" targetRef="refuseService">       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${secondLevelPass}]]></conditionExpression>     </sequenceFlow>     <serviceTask id="refuseService" name="不通過時業務處理" activiti:class="com.siemens.pms.act.service.impl.DemoAuditProcessor"></serviceTask>     <sequenceFlow id="flow6" name="不通過" sourceRef="secondLevelAudit" targetRef="refuseService">       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!secondLevelPass}]]></conditionExpression>     </sequenceFlow>     <endEvent id="accept" name="失敗"></endEvent>     <sequenceFlow id="flow8" sourceRef="refuseService" targetRef="accept"></sequenceFlow>     <sequenceFlow id="flow9" name="不通過" sourceRef="firstLevelAudit" targetRef="refuseService">       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!firstLevelPass}]]></conditionExpression>     </sequenceFlow>     <sequenceFlow id="flow10" name="通過" sourceRef="secondLevelAudit" targetRef="acceptService">       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${secondLevelPass}]]></conditionExpression>     </sequenceFlow>     <sequenceFlow id="flow11" sourceRef="acceptService" targetRef="refuse"></sequenceFlow>     <exclusiveGateway id="exclusivegateway1" name="是否二級"></exclusiveGateway>     <sequenceFlow id="flow14" name="是" sourceRef="exclusivegateway1" targetRef="secondLevelAudit">       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${secondLevel!=null}]]></conditionExpression>     </sequenceFlow>     <sequenceFlow id="flow15" name="否" sourceRef="exclusivegateway1" targetRef="acceptService">       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${secondLevel==null}]]></conditionExpression>     </sequenceFlow>     <sequenceFlow id="flow16" name="通過" sourceRef="firstLevelAudit" targetRef="exclusivegateway1">       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${firstLevelPass}]]></conditionExpression>     </sequenceFlow>   </process>   <bpmndi:BPMNDiagram id="BPMNDiagram_act_demo_audit">     <bpmndi:BPMNPlane bpmnElement="act_demo_audit" id="BPMNPlane_act_demo_audit">       <bpmndi:BPMNShape bpmnElement="Start" id="BPMNShape_Start">         <omgdc:Bounds height="51.0" width="71.0" x="30.0" y="165.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="firstLevelAudit" id="BPMNShape_firstLevelAudit">         <omgdc:Bounds height="61.0" width="161.0" x="140.0" y="160.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="secondLevelAudit" id="BPMNShape_secondLevelAudit">         <omgdc:Bounds height="61.0" width="181.0" x="480.0" y="160.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="refuse" id="BPMNShape_refuse">         <omgdc:Bounds height="51.0" width="71.0" x="1020.0" y="165.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="acceptService" id="BPMNShape_acceptService">         <omgdc:Bounds height="81.0" width="151.0" x="780.0" y="150.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="refuseService" id="BPMNShape_refuseService">         <omgdc:Bounds height="61.0" width="181.0" x="480.0" y="290.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="accept" id="BPMNShape_accept">         <omgdc:Bounds height="41.0" width="61.0" x="540.0" y="430.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">         <omgdc:Bounds height="40.0" width="40.0" x="360.0" y="170.0"></omgdc:Bounds>       </bpmndi:BPMNShape>       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">         <omgdi:waypoint x="101.0" y="190.0"></omgdi:waypoint>         <omgdi:waypoint x="140.0" y="190.0"></omgdi:waypoint>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">         <omgdi:waypoint x="570.0" y="221.0"></omgdi:waypoint>         <omgdi:waypoint x="570.0" y="290.0"></omgdi:waypoint>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">         <omgdi:waypoint x="570.0" y="221.0"></omgdi:waypoint>         <omgdi:waypoint x="570.0" y="290.0"></omgdi:waypoint>         <bpmndi:BPMNLabel>           <omgdc:Bounds height="16.0" width="48.0" x="570.0" y="221.0"></omgdc:Bounds>         </bpmndi:BPMNLabel>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">         <omgdi:waypoint x="570.0" y="351.0"></omgdi:waypoint>         <omgdi:waypoint x="570.0" y="430.0"></omgdi:waypoint>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">         <omgdi:waypoint x="220.0" y="221.0"></omgdi:waypoint>         <omgdi:waypoint x="220.0" y="320.0"></omgdi:waypoint>         <omgdi:waypoint x="480.0" y="320.0"></omgdi:waypoint>         <bpmndi:BPMNLabel>           <omgdc:Bounds height="16.0" width="48.0" x="220.0" y="221.0"></omgdc:Bounds>         </bpmndi:BPMNLabel>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">         <omgdi:waypoint x="661.0" y="190.0"></omgdi:waypoint>         <omgdi:waypoint x="780.0" y="190.0"></omgdi:waypoint>         <bpmndi:BPMNLabel>           <omgdc:Bounds height="16.0" width="32.0" x="661.0" y="190.0"></omgdc:Bounds>         </bpmndi:BPMNLabel>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">         <omgdi:waypoint x="931.0" y="190.0"></omgdi:waypoint>         <omgdi:waypoint x="1020.0" y="190.0"></omgdi:waypoint>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">         <omgdi:waypoint x="400.0" y="190.0"></omgdi:waypoint>         <omgdi:waypoint x="480.0" y="190.0"></omgdi:waypoint>         <bpmndi:BPMNLabel>           <omgdc:Bounds height="16.0" width="16.0" x="400.0" y="190.0"></omgdc:Bounds>         </bpmndi:BPMNLabel>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow15" id="BPMNEdge_flow15">         <omgdi:waypoint x="380.0" y="170.0"></omgdi:waypoint>         <omgdi:waypoint x="380.0" y="88.0"></omgdi:waypoint>         <omgdi:waypoint x="578.0" y="88.0"></omgdi:waypoint>         <omgdi:waypoint x="855.0" y="88.0"></omgdi:waypoint>         <omgdi:waypoint x="855.0" y="150.0"></omgdi:waypoint>         <bpmndi:BPMNLabel>           <omgdc:Bounds height="16.0" width="16.0" x="380.0" y="170.0"></omgdc:Bounds>         </bpmndi:BPMNLabel>       </bpmndi:BPMNEdge>       <bpmndi:BPMNEdge bpmnElement="flow16" id="BPMNEdge_flow16">         <omgdi:waypoint x="301.0" y="190.0"></omgdi:waypoint>         <omgdi:waypoint x="360.0" y="190.0"></omgdi:waypoint>         <bpmndi:BPMNLabel>           <omgdc:Bounds height="16.0" width="32.0" x="301.0" y="190.0"></omgdc:Bounds>         </bpmndi:BPMNLabel>       </bpmndi:BPMNEdge>     </bpmndi:BPMNPlane>   </bpmndi:BPMNDiagram> </definitions>

核心API

ProcessEngine

說明:

  1. 在Activiti中最核心的類,其他的類都是由他而來。
  2. 產生方式:

在前面看到了兩種建立ProcessEngine(流程引擎)的方式,而這裡要簡化很多,呼叫ProcessEngines的getDefaultProceeEngine方法時會自動載入classpath下名為activiti.cfg.xml檔案。

  1. 可以產生RepositoryService
  1. 可以產生RuntimeService
  1. 可以產生TaskService

各個Service的作用:

RepositoryService

管理流程定義

RuntimeService

執行管理,包括啟動、推進、刪除流程例項等操作

TaskService

任務管理

HistoryService

歷史管理(執行完的資料的管理)

IdentityService

組織機構管理

FormService

一個可選服務,任務表單管理

ManagerService

RepositoryService

是Activiti的倉庫服務類。所謂的倉庫指流程定義文件的兩個檔案:bpmn檔案和流程圖片。

  1. 產生方式
  1. 可以產生DeploymentBuilder,用來定義流程部署的相關引數
  1. 刪除流程定義

RuntimeService

是activiti的流程執行服務類。可以從這個服務類中獲取很多關於流程執行相關的資訊。

TaskService

是activiti的任務服務類。可以從這個類中獲取任務的資訊。

HistoryService

是activiti的查詢歷史資訊的類。在一個流程執行完成後,這個物件為我們提供查詢歷史資訊。

ProcessDefinition

流程定義類。可以從這裡獲得資原始檔等。

ProcessInstance

代表流程定義的執行例項。如范冰冰請了一天的假,她就必須發出一個流程例項的申請。一個流程例項包括了所有的執行節點。我們可以利用這個物件來了解當前流程例項的進度等資訊。流程例項就表示一個流程從開始到結束的最大的流程分支,即一個流程中流程例項只有一個。

Execution

Activiti用這個物件去描述流程執行的每一個節點。在沒有併發的情況下,Execution就是同ProcessInstance。流程按照流程定義的規則執行一次的過程,就可以表示執行物件Execution。

如圖為ProcessInstance的原始碼:

從原始碼中可以看出ProcessInstance就是Execution。但在現實意義上有所區別:

在單線流程中,如上圖的貸款流程,ProcessInstance與Execution是一致的。

這個例子有一個特點:wire money(匯錢)和archive(存檔)是併發執行的。 這個時候,匯流排路代表ProcessInstance,而分線路中每個活動代表Execution。

總結:

* 一個流程中,執行物件可以存在多個,但是流程例項只能有一個。

* 當流程按照規則只執行一次的時候,那麼流程例項就是執行物件。