部署流程定义
我们现在准备为Activiti引擎添加额外的BPM逻辑。
为此,正如我们的OnboardingRequest
Java类的名称所示,我们将使用简单的入职流程。在这个例子中,我们将输入数据,然后,如果经验年数超过3,则将发布个性化入职欢迎消息的任务。在该任务中,用户将手动将数据输入一个伪后端系统。如果工作经验在3年或以下,那么只需简单地、一般地、自动地将数据集成到一个伪后端系统中。
Activiti的流程引擎兼容BPMN 2.0标准,在视觉上,上面的流程可以这样建模:
这个例子非常简单,而且,根据要求,可以通过几种不同的方式对其进行建模。虽然它也可以协调简单的流程,但请注意,Activiti可以处理非常复杂的流程,包括数十个、数百个甚至数千个步骤。
上面的可视化流程模型的底层是BPMN的XML结构,在这种情况下,XML文档是onboarding.bpmn20.xml
,这个快速入门不会深入到底层XML BPMN结构的深度,专注于针对Activiti API开发的机制并将Activiti嵌入到你的应用程序中。然而,为了支持下面的逻辑,这里是相关BPMN形状和底层XML中编码的定义逻辑的摘要:
BPMN形状 |
Onboarding.bpmn20.xml 行 |
注释 |
---|---|---|
4 | 开始事件 | |
5-10 | 用户任务收集2个表单属性:“fullName”和“yearsOfExperience”; 请注意,第9行的候选组设置为“管理员”。 |
|
14-18 | 用户任务收集1表单属性:“personalWelcomeTime”; 请注意,第22行的候选组设置为“管理员”。 |
|
21-24 | 脚本任务表示数据自动输入到伪后端; 请注意,虽然简单,但有一个简单的脚本可以设置一个流程变量 autoWelcomeTime
|
|
25 26-28 25,26 |
定义“多年经验”专属网关; (决定将产生一条或另一条路径。) 使用yearsOfExperience变量表示“> 3”逻辑: ${yearsOfExperience > 3} 在专属网关上,注意指向“automatedIntroPath”的默认节,表示条件“>3”的逻辑“else”。 |
|
19 | 结束事件 |
下载onboarding.bpmn20.xml
文件,下面的整个XML结构,并将onboarding.bpmn20.xml
文件复制到路径$mvnProject
/src/main/resources/。
文件:$mvnProject/src/main/resources/onboarding.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="onboarding" name="Onboarding" isExecutable="true">
<startEvent id="startOnboarding" name="Start" activiti:initiator="initiator"></startEvent>
<userTask id="enterOnboardingData" name="Enter Data" activiti:assignee="${initiator}" activiti:candidateGroups="managers">
<extensionElements>
<activiti:formProperty id="fullName" name="Full Name" type="string"></activiti:formProperty>
<activiti:formProperty id="yearsOfExperience" name="Years of Experience" type="long" required="true"></activiti:formProperty>
</extensionElements>
</userTask>
<sequenceFlow id="sid-1337EA98-7364-4198-B5D9-30F5341D6918" sourceRef="startOnboarding" targetRef="enterOnboardingData"></sequenceFlow>
<exclusiveGateway id="decision" name="Years of Experience" default="automatedIntroPath"></exclusiveGateway>
<sequenceFlow id="sid-42BE5661-C3D5-4DE6-96F5-73D34822727A" sourceRef="enterOnboardingData" targetRef="decision"></sequenceFlow>
<userTask id="personalizedIntro" name="Personalized Introduction and Data Entry" activiti:assignee="${initiator}" activiti:candidateGroups="managers">
<extensionElements>
<activiti:formProperty id="personalWelcomeTime" name="Personal Welcome Time" type="date" datePattern="MM-dd-yyyy hh:mm"></activiti:formProperty>
</extensionElements>
</userTask>
<endEvent id="endOnboarding" name="End"></endEvent>
<sequenceFlow id="sid-37A73ACA-2E23-400B-96F3-71F77738DAFA" sourceRef="automatedIntro" targetRef="endOnboarding"></sequenceFlow>
<scriptTask id="automatedIntro" name="Generic and Automated Data Entry" scriptFormat="javascript" activiti:autoStoreVariables="false">
<script><![CDATA[var dateAsString = new Date().toString();
execution.setVariable("autoWelcomeTime", dateAsString);]]></script>
</scriptTask>
<sequenceFlow id="automatedIntroPath" sourceRef="decision" targetRef="automatedIntro"></sequenceFlow>
<sequenceFlow id="personalizedIntroPath" name=">3" sourceRef="decision" targetRef="personalizedIntro">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${yearsOfExperience > 3}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="sid-BA6F061B-47B6-428B-8CE6-739244B14BD6" sourceRef="personalizedIntro" targetRef="endOnboarding"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_onboarding">
<bpmndi:BPMNPlane bpmnElement="onboarding" id="BPMNPlane_onboarding">
<bpmndi:BPMNShape bpmnElement="startOnboarding" id="BPMNShape_startOnboarding">
<omgdc:Bounds height="30.0" width="30.0" x="155.0" y="145.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="enterOnboardingData" id="BPMNShape_enterOnboardingData">
<omgdc:Bounds height="80.0" width="100.0" x="240.0" y="120.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="decision" id="BPMNShape_decision">
<omgdc:Bounds height="40.0" width="40.0" x="385.0" y="140.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="personalizedIntro" id="BPMNShape_personalizedIntro">
<omgdc:Bounds height="80.0" width="100.0" x="519.0" y="15.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endOnboarding" id="BPMNShape_endOnboarding">
<omgdc:Bounds height="28.0" width="28.0" x="725.0" y="165.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="automatedIntro" id="BPMNShape_automatedIntro">
<omgdc:Bounds height="80.0" width="100.0" x="520.0" y="255.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-37A73ACA-2E23-400B-96F3-71F77738DAFA" id="BPMNEdge_sid-37A73ACA-2E23-400B-96F3-71F77738DAFA">
<omgdi:waypoint x="570.0" y="255.0"></omgdi:waypoint>
<omgdi:waypoint x="570.0" y="179.0"></omgdi:waypoint>
<omgdi:waypoint x="725.0" y="179.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-1337EA98-7364-4198-B5D9-30F5341D6918" id="BPMNEdge_sid-1337EA98-7364-4198-B5D9-30F5341D6918">
<omgdi:waypoint x="185.0" y="160.0"></omgdi:waypoint>
<omgdi:waypoint x="240.0" y="160.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="automatedIntroPath" id="BPMNEdge_automatedIntroPath">
<omgdi:waypoint x="405.0" y="180.0"></omgdi:waypoint>
<omgdi:waypoint x="405.0" y="295.0"></omgdi:waypoint>
<omgdi:waypoint x="520.0" y="295.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="personalizedIntroPath" id="BPMNEdge_personalizedIntroPath">
<omgdi:waypoint x="405.0" y="140.0"></omgdi:waypoint>
<omgdi:waypoint x="405.0" y="55.0"></omgdi:waypoint>
<omgdi:waypoint x="519.0" y="55.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-42BE5661-C3D5-4DE6-96F5-73D34822727A" id="BPMNEdge_sid-42BE5661-C3D5-4DE6-96F5-73D34822727A">
<omgdi:waypoint x="340.0" y="160.0"></omgdi:waypoint>
<omgdi:waypoint x="385.0" y="160.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-BA6F061B-47B6-428B-8CE6-739244B14BD6" id="BPMNEdge_sid-BA6F061B-47B6-428B-8CE6-739244B14BD6">
<omgdi:waypoint x="619.0" y="55.0"></omgdi:waypoint>
<omgdi:waypoint x="739.0" y="55.0"></omgdi:waypoint>
<omgdi:waypoint x="739.0" y="165.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
添加到OnboardingRequest.java
,如下图所示:
文件:$mvnProject/src/main/java/com/example/OnboardingRequest.java
package com.example;
import java.text.ParseException;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
public class OnboardingRequest {
public static void main(String[] args) throws ParseException {
ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000")
.setJdbcUsername("sa")
.setJdbcPassword("")
.setJdbcDriver("org.h2.Driver")
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
ProcessEngine processEngine = cfg.buildProcessEngine();
String pName = processEngine.getName();
String ver = ProcessEngine.VERSION;
System.out.println("ProcessEngine [" + pName + "] Version: [" + ver + "]");
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("onboarding.bpmn20.xml").deploy();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.deploymentId(deployment.getId()).singleResult();
System.out.println(
"Found process definition ["
+ processDefinition.getName() + "] with id ["
+ processDefinition.getId() + "]");
}
}
文件:$mvnProject/src/main/java/com/example/OnboardingRequest.java
添加行 | 说明 |
---|---|
25-27 | 加载提供的BPMN模型并将其部署到Activiti流程引擎。 |
28-33 | 检索已部署的模型,证明它位于Activiti存储库中。 |
有关BPMN及其在Activiti中的使用的更多信息,请参阅Activiti用户指南中的各个部分。
通过运行“mvn package”打包代码。
像以前一样运行Java程序,示例输出如下所示。
命令:java -jar target/ActivitiDeveloperQuickStart-0.0.1-SNAPSHOT-jar-with-dependencies.jar
或 java -jar target/$quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar
...
02:01:19,277 [main] INFO org.activiti.engine.impl.ProcessEngineImpl - ProcessEngine default created
processEngine [default] version: [5.22.0.0]
...
02:01:19,327 [main] DEBUG org.activiti.engine.impl.bpmn.deployer.BpmnDeployer - Processing deployment null
02:01:19,327 [main] INFO org.activiti.engine.impl.bpmn.deployer.BpmnDeployer - Processing resource onboarding.bpmn20.xml
02:01:19,444 [main] DEBUG org.activiti.engine.impl.bpmn.parser.handler.ProcessParseHandler - Parsing process
...
02:01:21,696 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 667346055 to pool.
02:01:21,696 [main] DEBUG org.activiti.engine.impl.interceptor.LogInterceptor - --- DeployCmd finished --------------------------------------------------------
...
02:01:21,696 [main] DEBUG org.activiti.engine.impl.interceptor.LogInterceptor - --- starting ProcessDefinitionQueryImpl --------------------------------------------------------
...
02:01:21,710 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource - Returned connection 667346055 to pool.
02:01:21,710 [main] DEBUG org.activiti.engine.impl.interceptor.LogInterceptor - --- ProcessDefinitionQueryImpl finished --------------------------------------------------------
02:01:21,710 [main] DEBUG org.activiti.engine.impl.interceptor.LogInterceptor -
Found process definition [Onboarding] with id [onboarding:1:4]
这里感兴趣的关键输出是列表行,它记录了流程名称“Onboarding”和“onboarding:1:4”的唯一流程ID(包括部署版本)。
你的应用程序现在在运行时部署Onboarding流程。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。