首页
/ Flowable多引擎集成:BPMN流程引擎实战

Flowable多引擎集成:BPMN流程引擎实战

2026-02-04 04:12:49作者:平淮齐Percy

本文深入探讨了Flowable BPMN流程引擎的核心功能与实践应用。BPMN 2.0作为业务流程建模的行业标准,提供了丰富的图形符号和语义规范。Flowable作为强大的BPMN 2.0流程引擎,支持完整的BPMN模型,包括事件、活动、网关和连接对象等核心元素。文章详细介绍了程序化BPMN模型构建、扩展元素使用、高级建模模式以及流程定义部署与版本管理机制,为开发者提供了全面的实战指导。

BPMN 2.0标准流程建模

BPMN(Business Process Model and Notation)2.0是业务流程建模的行业标准,它提供了一套丰富的图形符号和语义规范,用于描述业务流程的执行逻辑。Flowable作为一款强大的BPMN 2.0流程引擎,提供了完整的BPMN模型支持,让开发者能够以编程方式或XML方式定义复杂的业务流程。

BPMN 2.0核心元素

Flowable支持BPMN 2.0规范中的所有核心元素,包括事件(Events)、活动(Activities)、网关(Gateways)和连接对象(Connecting Objects)。每个元素都有对应的Java模型类,便于程序化构建流程模型。

流程定义结构

一个完整的BPMN流程定义包含以下基本结构:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:flowable="http://flowable.org/bpmn"
             targetNamespace="Examples">
    
    <process id="myProcess" name="My Business Process" isExecutable="true">
        <!-- 流程元素定义 -->
    </process>
    
</definitions>

核心建模元素详解

1. 事件(Events)

事件表示流程中发生的事情,分为开始事件、中间事件和结束事件:

// 创建开始事件
StartEvent startEvent = new StartEvent();
startEvent.setId("startEvent1");
startEvent.setName("流程开始");

// 创建定时器事件定义
TimerEventDefinition timerDef = new TimerEventDefinition();
timerDef.setTimeDuration("PT5M"); // 5分钟后触发
startEvent.getEventDefinitions().add(timerDef);

// 创建结束事件
EndEvent endEvent = new EndEvent();
endEvent.setId("endEvent1");
endEvent.setName("流程结束");
2. 活动(Activities)

活动是流程中的工作单元,包括任务和子流程:

// 创建用户任务
UserTask userTask = new UserTask();
userTask.setId("reviewTask");
userTask.setName("审批任务");
userTask.setAssignee("kermit"); // 指定处理人

// 创建服务任务
ServiceTask serviceTask = new ServiceTask();
serviceTask.setId("javaService");
serviceTask.setName("Java服务调用");
serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
serviceTask.setImplementation("com.example.MyServiceTask");
3. 网关(Gateways)

网关用于控制流程的分支和合并:

// 创建排他网关
ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
exclusiveGateway.setId("decisionGateway");
exclusiveGateway.setName("决策网关");

// 创建并行网关
ParallelGateway parallelGateway = new ParallelGateway();
parallelGateway.setId("forkGateway");
parallelGateway.setName("分支网关");
4. 序列流(Sequence Flows)

序列流连接流程元素,定义执行顺序:

SequenceFlow flow1 = new SequenceFlow();
flow1.setId("flow1");
flow1.setSourceRef("startEvent1");
flow1.setTargetRef("reviewTask");
flow1.setName("开始到审批");

// 条件序列流
SequenceFlow conditionalFlow = new SequenceFlow();
conditionalFlow.setId("conditionalFlow");
conditionalFlow.setSourceRef("decisionGateway");
conditionalFlow.setTargetRef("approvalTask");
conditionalFlow.setConditionExpression("${approvalRequired == true}");

程序化BPMN模型构建

Flowable提供了丰富的API用于程序化构建BPMN模型:

// 创建BPMN模型
BpmnModel bpmnModel = new BpmnModel();

// 创建流程
Process process = new Process();
process.setId("simpleProcess");
process.setName("简单审批流程");
process.setExecutable(true);

// 添加流程元素
process.addFlowElement(startEvent);
process.addFlowElement(userTask);
process.addFlowElement(endEvent);
process.addFlowElement(flow1);
process.addFlowElement(flow2);

// 将流程添加到模型
bpmnModel.getProcesses().add(process);

// 转换为XML
byte[] xmlBytes = new BpmnXMLConverter().convertToXML(bpmnModel);
String bpmnXml = new String(xmlBytes, StandardCharsets.UTF_8);

BPMN扩展元素

Flowable提供了丰富的扩展元素来增强BPMN的功能:

表单属性

<userTask id="formTask" name="表单任务">
    <extensionElements>
        <flowable:formProperty id="approval" 
                              name="审批意见" 
                              type="string" 
                              required="true"/>
        <flowable:formProperty id="priority" 
                              name="优先级" 
                              type="enum"
                              expression="${priorityOptions}"/>
    </extensionElements>
</userTask>

执行监听器

// 添加执行监听器
FlowableListener listener = new FlowableListener();
listener.setEvent("start");
listener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION);
listener.setImplementation("${executionListenerBean.onStart}");
startEvent.getExecutionListeners().add(listener);

多实例配置

<userTask id="multiInstanceTask" name="多实例审批">
    <multiInstanceLoopCharacteristics 
        flowable:collection="${approvers}" 
        flowable:elementVariable="approver">
        <completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.6}</completionCondition>
    </multiInstanceLoopCharacteristics>
</userTask>

高级建模模式

子流程调用

// 创建调用活动
CallActivity callActivity = new CallActivity();
callActivity.setId("callSubProcess");
callActivity.setName("调用子流程");
callActivity.setCalledElement("subProcessDefinitionKey");
callActivity.setInheritVariables(true);

// 输入参数映射
IOParameter inParam = new IOParameter();
inParam.setSource("mainProcessVariable");
inParam.setTarget("subProcessVariable");
callActivity.addInParameter(inParam);

// 输出参数映射
IOParameter outParam = new IOParameter();
outParam.setSource("subProcessResult");
outParam.setTarget("mainProcessResult");
callActivity.addOutParameter(outParam);

错误边界事件

// 创建错误边界事件
BoundaryEvent errorBoundaryEvent = new BoundaryEvent();
errorBoundaryEvent.setId("errorCatch");
errorBoundaryEvent.setAttachedToRefId("serviceTask");
errorBoundaryEvent.setCancelActivity(true);

// 错误事件定义
ErrorEventDefinition errorDef = new ErrorEventDefinition();
errorDef.setErrorCode("SERVICE_ERROR");
errorBoundaryEvent.getEventDefinitions().add(errorDef);

信号事件

// 创建信号中间抛出事件
IntermediateThrowEvent signalEvent = new IntermediateThrowEvent();
signalEvent.setId("throwSignal");

SignalEventDefinition signalDef = new SignalEventDefinition();
signalDef.setSignalRef("notificationSignal");
signalEvent.getEventDefinitions().add(signalDef);

BPMN模型验证

Flowable提供了强大的模型验证功能:

// 创建流程验证器
ProcessValidatorFactory validatorFactory = new ProcessValidatorFactory();
ProcessValidator processValidator = validatorFactory.createDefaultProcessValidator();

// 验证BPMN模型
List<ValidationError> validationErrors = processValidator.validate(bpmnModel);

if (validationErrors.isEmpty()) {
    System.out.println("BPMN模型验证通过");
} else {
    for (ValidationError error : validationErrors) {
        System.out.println("验证错误: " + error.getProblem() + " at " + error.getDefaultDescription());
    }
}

建模最佳实践

  1. 命名规范:为所有元素提供有意义的ID和名称
  2. 版本控制:使用明确的版本标识流程定义
  3. 错误处理:为关键任务添加适当的错误边界事件
  4. 性能考虑:避免过度复杂的网关嵌套
  5. 可维护性:使用子流程模块化复杂逻辑

流程建模示例

以下是一个完整的请假审批流程示例:

flowchart TD
    A[开始事件] --> B[填写请假申请]
    B --> C{经理审批}
    C -->|批准| D[HR备案]
    C -->|拒绝| E[通知申请人]
    D --> F[结束事件]
    E --> F

对应的BPMN模型代码:

BpmnModel leaveProcessModel = new BpmnModel();
Process leaveProcess = new Process();
leaveProcess.setId("leaveApprovalProcess");
leaveProcess.setName("请假审批流程");

// 开始事件
StartEvent startEvent = new StartEvent();
startEvent.setId("startEvent");

// 用户任务:填写申请
UserTask applyTask = new UserTask();
applyTask.setId("applyLeave");
applyTask.setName("填写请假申请");
applyTask.setAssignee("${applicant}");

// 排他网关:审批决策
ExclusiveGateway approvalGateway = new ExclusiveGateway();
approvalGateway.setId("approvalDecision");

// 用户任务:经理审批
UserTask managerApprove = new UserTask();
managerApprove.setId("managerApproval");
managerApprove.setName("经理审批");
managerApprove.setCandidateGroups("managers");

// 用户任务:HR备案
UserTask hrRecord = new UserTask();
hrRecord.setId("hrRecording");
hrRecord.setName("HR备案");
hrRecord.setCandidateGroups("hr");

// 服务任务:通知申请人
ServiceTask notifyApplicant = new ServiceTask();
notifyTask.setId("notifyApplicant");
notifyTask.setName("通知申请人");
notifyTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
notifyTask.setImplementation("${notificationService}");

// 结束事件
EndEvent endEvent = new EndEvent();
endEvent.setId("endEvent");

// 序列流
SequenceFlow startToApply = createSequenceFlow("startToApply", "startEvent", "applyLeave");
SequenceFlow applyToDecision = createSequenceFlow("applyToDecision", "applyLeave", "approvalDecision");
SequenceFlow decisionToApprove = createSequenceFlow("decisionToApprove", "approvalDecision", "managerApproval", "${approved == true}");
SequenceFlow decisionToReject = createSequenceFlow("decisionToReject", "approvalDecision", "notifyApplicant", "${approved == false}");
SequenceFlow approveToHR = createSequenceFlow("approveToHR", "managerApproval", "hrRecording");
SequenceFlow hrToEnd = createSequenceFlow("hrToEnd", "hrRecording", "endEvent");
SequenceFlow notifyToEnd = createSequenceFlow("notifyToEnd", "notifyApplicant", "endEvent");

// 添加所有元素到流程
leaveProcess.addFlowElement(startEvent);
leaveProcess.addFlowElement(applyTask);
leaveProcess.addFlowElement(approvalGateway);
leaveProcess.addFlowElement(managerApprove);
leaveProcess.addFlowElement(hrRecord);
leaveProcess.addFlowElement(notifyApplicant);
leaveProcess.addFlowElement(endEvent);
leaveProcess.addFlowElement(startToApply);
leaveProcess.addFlowElement(applyToDecision);
leaveProcess.addFlowElement(decisionToApprove);
leaveProcess.addFlowElement(decisionToReject);
leaveProcess.addFlowElement(approveToHR);
leaveProcess.addFlowElement(hrToEnd);
leaveProcess.addFlowElement(notifyToEnd);

leaveProcessModel.getProcesses().add(leaveProcess);

通过Flowable的BPMN 2.0支持,开发者可以构建出符合行业标准的复杂业务流程,同时享受到强大的执行引擎带来的性能和可靠性保障。

流程定义部署与版本管理

Flowable BPMN引擎提供了强大的流程定义部署和版本管理机制,这是构建企业级工作流系统的核心功能。通过灵活的部署API和智能的版本控制策略,开发者可以轻松管理业务流程的生命周期。

部署构建器与多源部署

Flowable通过DeploymentBuilder接口提供了多种部署方式,支持从不同来源加载流程定义资源:

// 从类路径资源部署
repositoryService.createDeployment()
    .addClasspathResource("processes/leave-approval.bpmn20.xml")
    .name("请假审批流程")
    .deploy();

// 从输入流部署
InputStream inputStream = new FileInputStream("processes/expense-report.bpmn20.xml");
repositoryService.createDeployment()
    .addInputStream("expense-process.bpmn20.xml", inputStream)
    .deploy();

// 从字符串内容部署
String bpmnContent = "<definitions>...</definitions>";
repositoryService.createDeployment()
    .addString("dynamic-process.bpmn20.xml", bpmnContent)
    .deploy();

// 从ZIP包批量部署
ZipInputStream zipInputStream = new ZipInputStream(
    new FileInputStream("process-package.zip"));
repositoryService.createDeployment()
    .addZipInputStream(zipInputStream)
    .deploy();

部署配置选项

部署时可以通过丰富的配置选项来控制部署行为:

Deployment deployment = repositoryService.createDeployment()
    .addClasspathResource("processes/order-process.bpmn20.xml")
    .name("订单处理流程")
    .category("SALES")
    .key("ORDER_PROCESS")
    .tenantId("tenant1")  // 多租户支持
    .disableBpmnValidation()  // 禁用BPMN验证
    .disableSchemaValidation()  // 禁用XML Schema验证
    .enableDuplicateFiltering()  // 启用重复过滤
    .activateProcessDefinitionsOn(new Date())  // 指定激活时间
    .deploymentProperty("customProperty", "value")  // 自定义部署属性
    .deploy();

版本管理机制

Flowable采用智能的版本控制策略,为每个流程定义维护版本号:

flowchart TD
    A[部署新流程定义] --> B{检查流程Key是否存在?}
    B -->|否| C[创建版本1]
    B -->|是| D[获取当前最高版本]
    D --> E[版本号+1]
    E --> F[创建新版本]
    C --> G[部署完成]
    F --> G

版本管理的关键特性:

特性 描述 示例
自动版本递增 相同key的流程定义部署时版本自动+1 v1 → v2 → v3
版本查询 支持按版本号查询特定版本 processDefinitionVersion(2)
多版本共存 多个版本可以同时存在 v1, v2, v3 并行
版本激活控制 可以控制流程定义的激活状态 activateProcessDefinitionsOn(date)

重复部署过滤

Flowable提供了智能的重复部署检测机制,避免不必要的重复部署:

// 启用重复过滤
repositoryService.createDeployment()
    .addClasspathResource("processes/approval.bpmn20.xml")
    .enableDuplicateFiltering()
    .deploy();

// 基于内容的重复检测
// Flowable会比较资源内容的MD5哈希值
// 如果内容相同且启用了重复过滤,则不会创建新部署

部署查询与管理

通过RepositoryService可以查询和管理部署信息:

// 查询所有部署
List<Deployment> deployments = repositoryService.createDeploymentQuery().list();

// 按名称查询
Deployment deployment = repositoryService.createDeploymentQuery()
    .deploymentName("请假审批流程")
    .singleResult();

// 按时间范围查询
List<Deployment> recentDeployments = repositoryService.createDeploymentQuery()
    .deploymentAfter(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000))
    .list();

// 删除部署(级联删除相关资源)
repositoryService.deleteDeployment(deploymentId, true);

流程定义查询与版本控制

流程定义查询支持丰富的版本相关操作:

// 查询最新版本的流程定义
ProcessDefinition latestProcess = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey("leaveApproval")
    .latestVersion()
    .singleResult();

// 查询特定版本的流程定义
ProcessDefinition version2Process = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey("leaveApproval")
    .processDefinitionVersion(2)
    .singleResult();

// 查询所有版本的流程定义
List<ProcessDefinition> allVersions = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey("leaveApproval")
    .orderByProcessDefinitionVersion().asc()
    .list();

// 获取流程定义版本统计
long versionCount = repositoryService.createProcessDefinitionQuery()
    .processDefinitionKey("leaveApproval")
    .count();

部署策略与最佳实践

在实际项目中,建议采用以下部署策略:

  1. 环境隔离部署:为开发、测试、生产环境使用不同的部署分类
  2. 版本标签管理:在部署名称中包含版本信息和构建标识
  3. 回滚机制:保留历史版本部署以便快速回滚
  4. 部署验证:在生产部署前进行严格的验证测试
// 生产环境部署示例
String deploymentName = "order-process-v2.1.0-" + System.currentTimeMillis();
Deployment productionDeployment = repositoryService.createDeployment()
    .addClasspathResource("processes/order-process.bpmn20.xml")
    .name(deploymentName)
    .category("PRODUCTION")
    .enableDuplicateFiltering()
    .deploy();

通过Flowable强大的部署和版本管理功能,企业可以构建稳定、可维护的业务流程管理系统,确保流程变更的可控性和可追溯性。

流程实例启动与执行控制

Flowable BPMN引擎提供了强大而灵活的流程实例启动和执行控制机制,支持多种启动方式、变量传递、业务键管理以及细粒度的执行流程控制。本文将深入探讨Flowable中流程实例的启动机制、执行控制原理以及最佳实践。

流程实例启动机制

Flowable通过RuntimeService接口提供了丰富的流程实例启动方法,支持多种启动场景:

1. 基本启动方式

通过流程定义Key启动

// 最简单的启动方式
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("orderProcess");

// 带业务键启动
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
    "orderProcess", "ORDER-12345");

// 带变量启动
Map<String, Object> variables = new HashMap<>();
variables.put("customerId", "CUST-001");
variables.put("orderAmount", 1000.0);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
    "orderProcess", variables);

// 完整参数启动
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
    "orderProcess", "ORDER-12345", variables);

通过流程定义ID启动

// 精确指定流程版本
ProcessInstance processInstance = runtimeService.startProcessInstanceById(
    "orderProcess:1:1234");

// 带业务键和变量
ProcessInstance processInstance = runtimeService.startProcessInstanceById(
    "orderProcess:1:1234", "ORDER-12345", variables);

2. 消息启动机制

Flowable支持通过消息事件启动流程实例,实现事件驱动的流程触发:

// 通过消息名称启动
ProcessInstance processInstance = runtimeService.startProcessInstanceByMessage(
    "orderCreatedMessage");

// 带业务键和消息载荷
Map<String, Object> messagePayload = new HashMap<>();
messagePayload.put("orderId", "ORDER-001");
messagePayload.put("customerName", "John Doe");
ProcessInstance processInstance = runtimeService.startProcessInstanceByMessage(
    "orderCreatedMessage", "ORDER-001", messagePayload);

3. 表单启动机制

对于需要表单数据的流程启动,Flowable提供了表单集成支持:

// 通过表单启动流程
Map<String, Object> formVariables = new HashMap<>();
formVariables.put("applicantName", "张三");
formVariables.put("applicationType", "请假");
ProcessInstance processInstance = runtimeService.startProcessInstanceWithForm(
    "leaveProcess:1:5678", "approve", formVariables, "张三的请假申请");

流程实例启动流程解析

Flowable的流程实例启动过程遵循严谨的执行流程,如下图所示:

sequenceDiagram
    participant Client
    participant RuntimeService
    participant StartProcessInstanceCmd
    participant ProcessInstanceHelper
    participant ExecutionEntityManager
    participant Agenda

    Client->>RuntimeService: startProcessInstanceByKey()
    RuntimeService->>StartProcessInstanceCmd: execute()
    
    StartProcessInstanceCmd->>ProcessInstanceHelper: createProcessInstance()
    
    ProcessInstanceHelper->>ExecutionEntityManager: createProcessInstanceExecution()
    ExecutionEntityManager-->>ProcessInstanceHelper: ExecutionEntity
    
    ProcessInstanceHelper->>ProcessInstanceHelper: setVariables()
    ProcessInstanceHelper->>ExecutionEntityManager: createChildExecution()
    
    ProcessInstanceHelper->>Agenda: planContinueProcessOperation()
    Agenda-->>ProcessInstanceHelper: Operation scheduled
    
    ProcessInstanceHelper-->>StartProcessInstanceCmd: ProcessInstance
    StartProcessInstanceCmd-->>RuntimeService: ProcessInstance
    RuntimeService-->>Client: ProcessInstance

启动过程详细步骤

  1. 流程定义验证

    • 检查流程定义是否存在且未挂起
    • 验证租户上下文(如果使用多租户)
  2. 流程实例创建

    • 创建主流程实例执行实体(ExecutionEntity)
    • 设置业务键、流程实例名称等元数据
    • 记录历史信息
  3. 变量处理

    • 处理流程数据对象(Data Objects)
    • 设置传入的流程变量
    • 处理瞬态变量(Transient Variables)
  4. 执行流创建

    • 创建子执行实体用于流程流转
    • 设置初始流元素(Start Event)
  5. 执行计划

    • 通过Agenda计划继续流程操作
    • 触发流程开始事件监听器

执行控制机制

Flowable使用Agenda模式来控制流程的执行流转,确保流程按照BPMN规范正确执行。

Agenda执行控制

classDiagram
    class FlowableEngineAgenda {
        +planContinueProcessOperation(ExecutionEntity execution)
        +planTakeOutgoingSequenceFlowsOperation(ExecutionEntity execution, boolean evaluateConditions)
        +planTriggerExecutionOperation(ExecutionEntity execution)
    }
    
    class ContinueProcessOperation {
        +run()
        -continueThroughFlowNode(FlowNode flowNode)
        -executeSynchronous(FlowNode flowNode)
        -executeAsynchronous(FlowNode flowNode)
    }
    
    class ExecutionEntity {
        -String id
        -String processInstanceId
        -FlowElement currentFlowElement
        -boolean active
        +getCurrentFlowElement() FlowElement
        +setCurrentFlowElement(FlowElement element)
    }
    
    FlowableEngineAgenda --> ContinueProcessOperation
    ContinueProcessOperation --> ExecutionEntity

同步与异步执行

Flowable支持同步和异步两种执行模式:

同步执行

// 同步执行活动节点
public void executeSynchronous(FlowNode flowNode) {
    // 记录活动开始
    CommandContextUtil.getActivityInstanceEntityManager(commandContext)
        .recordActivityStart(execution);
    
    // 执行开始监听器
    executeExecutionListeners(flowNode, ExecutionListener.EVENTNAME_START);
    
    // 创建边界事件
    List<ExecutionEntity> boundaryEventExecutions = 
        createBoundaryEvents(boundaryEvents, execution);
    
    // 执行活动行为
    ActivityBehavior activityBehavior = (ActivityBehavior) flowNode.getBehavior();
    if (activityBehavior != null) {
        executeActivityBehavior(activityBehavior, flowNode);
        executeBoundaryEvents(boundaryEvents, boundaryEventExecutions);
    } else {
        // 默认继续流出序列流
        CommandContextUtil.getAgenda().planTakeOutgoingSequenceFlowsOperation(execution, true);
    }
}

异步执行

// 异步执行活动节点
public void executeAsynchronous(FlowNode flowNode) {
    ProcessEngineConfigurationImpl config = CommandContextUtil.getProcessEngineConfiguration(commandContext);
    JobService jobService = config.getJobServiceConfiguration().getJobService();
    
    // 创建异步作业
    JobEntity job = JobUtil.createJob(execution, flowNode, 
        AsyncContinuationJobHandler.TYPE, config);
    
    // 保存并调度作业
    jobService.createAsyncJob(job, flowNode.isExclusive());
    jobService.scheduleAsyncJob(job);
}

高级启动特性

1. 流程实例构建器

Flowable提供了灵活的ProcessInstanceBuilder来构建复杂的启动场景:

ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
    .processDefinitionKey("complexProcess")
    .businessKey("BUS-789")
    .variable("priority", "high")
    .variable("dueDate", new Date())
    .transientVariable("initialData", largeDataObject)
    .name("重要业务流程实例")
    .tenantId("tenant1")
    .overrideDefinitionTenantId("tenant2")
    .start();

2. 启动拦截器

支持通过拦截器在启动前后执行自定义逻辑:

public interface StartProcessInstanceInterceptor {
    void beforeStartProcessInstance(StartProcessInstanceBeforeContext context);
    void afterStartProcessInstance(StartProcessInstanceAfterContext context);
}

// 配置拦截器
ProcessEngineConfigurationImpl config = new StandaloneProcessEngineConfiguration();
config.setStartProcessInstanceInterceptor(new CustomStartInterceptor());

3. 多实例流程启动

对于多实例流程,Flowable提供了专门的执行控制:

// 多实例执行控制
protected void executeMultiInstanceSynchronous(FlowNode flowNode) {
    if (!hasMultiInstanceRootExecution(execution, flowNode)) {
        execution = createMultiInstanceRootExecution(execution);
    }
    
    // 执行多实例行为
    ActivityBehavior activityBehavior = (ActivityBehavior) flowNode.getBehavior();
    if (activityBehavior != null) {
        executeActivityBehavior(activityBehavior, flowNode);
    }
}

执行状态管理

Flowable提供了完善的执行状态管理机制:

执行状态查询

// 查询流程实例
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
    .processInstanceId(processInstanceId)
    .singleResult();

// 查询执行流
List<Execution> executions = runtimeService.createExecutionQuery()
    .processInstanceId(processInstanceId)
    .list();

// 查询活动实例
List<ActivityInstance> activities = runtimeService.createActivityInstanceQuery()
    .processInstanceId(processInstanceId)
    .list();

执行状态控制

// 挂起流程实例
runtimeService.suspendProcessInstanceById(processInstanceId);

// 激活流程实例
runtimeService.activateProcessInstanceById(processInstanceId);

// 删除流程实例
runtimeService.deleteProcessInstance(processInstanceId, "业务取消");

// 修改变量
runtimeService.setVariable(executionId, "status", "updated");

最佳实践

1. 业务键的使用

// 使用有意义的业务键
String businessKey = "ORDER-" + orderId + "-" + System.currentTimeMillis();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
    "orderFulfillment", businessKey);

// 通过业务键查询
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
    .processInstanceBusinessKey(businessKey)
    .singleResult();

2. 变量管理策略

// 合理使用变量类型
Map<String, Object> variables = new HashMap<>();
variables.put("stringVar", "value"); // 字符串变量
variables.put("intVar", 100);        // 整数变量
variables.put("objectVar", new CustomDTO()); // 对象变量(需序列化)
variables.put("dateVar", new Date()); // 日期变量

// 使用瞬态变量处理大数据
Map<String, Object> transientVars = new HashMap<>();
transientVars.put("largeData", largeObject); // 不持久化到数据库

3. 错误处理与重试

try {
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
        "criticalProcess", businessKey, variables);
} catch (FlowableObjectNotFoundException e) {
    // 处理流程定义不存在
    logger.error("Process definition not found", e);
} catch (FlowableException e) {
    // 处理其他引擎异常
    logger.error("Failed to start process instance", e);
}

// 实现重试机制
int maxRetries = 3;
int retryCount = 0;
while (retryCount < maxRetries) {
    try {
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
            "unreliableProcess", businessKey, variables);
        break;
    } catch (Exception e) {
        retryCount++;
        if (retryCount >= maxRetries) {
            throw e;
        }
        Thread.sleep(1000 * retryCount); // 指数退避
    }
}

4. 性能优化建议

批量启动优化

// 使用批量操作减少数据库交互
for (int i = 0; i < batchSize; i++) {
    ProcessInstanceBuilder builder = runtimeService.createProcessInstanceBuilder()
        .processDefinitionKey("batchProcess")
        .businessKey("BATCH-" + i)
        .variable("index", i);
    
    if (i % 100 == 0) {
        // 定期提交以避免内存溢出
        commandContext.close();
        commandContext = commandContextFactory.createCommandContext();
    }
}

变量序列化优化

// 使用高效的序列化方式
public class OptimizedVariableSerializer implements VariableSerializer {
    @Override
    public byte[] serialize(Object value) {
        // 使用Kryo、Protobuf等高效序列化库
        return serializeWithKryo(value);
    }
    
    @Override
    public Object deserialize(byte[] bytes) {
        return deserializeWithKryo(bytes);
    }
}

// 配置自定义序列化器
processEngineConfiguration.setVariableSerializer(new OptimizedVariableSerializer());

Flowable的流程实例启动与执行控制机制提供了企业级业务流程管理所需的所有功能,从简单的流程启动到复杂的执行控制,都能满足各种业务场景的需求。通过合理使用这些特性,可以构建出高效、可靠、易维护的业务流程管理系统。

网关与边界事件处理机制

Flowable BPMN引擎提供了强大的网关和边界事件处理机制,这些功能是构建复杂业务流程的关键组件。网关用于控制流程的分支和合并,而边界事件则提供了在特定活动执行期间处理异常或特定条件的机制。

网关类型及其行为实现

Flowable支持多种BPMN网关类型,每种网关都有其特定的行为实现:

1. 排他网关(Exclusive Gateway)

排他网关是最常用的网关类型,用于在多个分支中选择一个路径执行。Flowable通过ExclusiveGatewayActivityBehavior类实现其逻辑:

public class ExclusiveGatewayActivityBehavior extends GatewayActivityBehavior {
    @Override
    public void leave(DelegateExecution execution) {
        // 评估所有出口序列流条件
        // 选择第一个条件为true的路径
        // 如果没有条件满足,选择默认路径
    }
}

排他网关的执行流程如下:

flowchart TD
    A[排他网关执行] --> B{评估序列流条件}
    B -->|条件1为true| C[执行路径1]
    B -->|条件2为true| D[执行路径2]
    B -->|所有条件为false| E[执行默认路径]
    C --> F[流程继续]
    D --> F
    E --> F

2. 并行网关(Parallel Gateway)

并行网关用于同时激活多个分支,所有分支必须完成后才能继续。ParallelGatewayActivityBehavior处理这种同步机制:

public class ParallelGatewayActivityBehavior extends AbstractBpmnActivityBehavior {
    @Override
    public void execute(DelegateExecution execution) {
        // 创建所有出口序列流的执行实例
        // 等待所有分支完成
    }
}

并行网关的同步机制:

网关行为 描述 实现类
分支创建 为每个出口序列流创建执行实例 ParallelGatewayActivityBehavior
同步等待 等待所有分支执行完成 内置同步机制
合并继续 所有分支完成后继续主流程 BpmnActivityBehavior

3. 包容网关(Inclusive Gateway)

包容网关允许同时激活满足条件的多个分支,提供了更灵活的流程控制:

public class InclusiveGatewayActivityBehavior extends AbstractBpmnActivityBehavior {
    @Override
    public void execute(DelegateExecution execution) {
        // 评估所有条件
        // 激活所有满足条件的路径
    }
    
    @Override
    public void executeInactive(ExecutionEntity executionEntity) {
        // 处理非活跃状态的执行
    }
}

边界事件处理机制

边界事件是附加在活动边界上的事件,用于处理活动执行期间的特定情况。Flowable提供了丰富的边界事件类型:

1. 定时器边界事件

BoundaryTimerEventActivityBehavior处理定时器边界事件,允许在活动执行期间设置超时:

public class BoundaryTimerEventActivityBehavior extends BoundaryEventActivityBehavior {
    @Override
    public void execute(DelegateExecution execution) {
        // 创建定时器作业
        // 监听定时器触发
    }
}

定时器边界事件配置示例:

<boundaryEvent id="timeoutEvent" attachedToRef="userTask">
    <timerEventDefinition>
        <timeDuration>PT1H</timeDuration>
    </timerEventDefinition>
</boundaryEvent>

2. 信号边界事件

信号边界事件通过BoundarySignalEventActivityBehavior处理,用于响应系统范围内的信号:

public class BoundarySignalEventActivityBehavior extends BoundaryEventActivityBehavior {
    @Override
    public void execute(DelegateExecution execution) {
        // 注册信号监听器
    }
    
    @Override
    public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
        // 处理信号触发
    }
}

3. 消息边界事件

消息边界事件使用BoundaryMessageEventActivityBehavior,允许活动等待特定消息:

public class BoundaryMessageEventActivityBehavior extends BoundaryEventActivityBehavior {
    @Override
    public void execute(DelegateExecution execution) {
        // 创建消息订阅
    }
    
    @Override
    public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
        // 处理消息到达
    }
}

事件网关与边界事件的协同工作

事件网关(Event Based Gateway)与边界事件可以协同工作,创建基于事件的决策点:

sequenceDiagram
    participant G as 事件网关
    participant B1 as 边界事件1
    participant B2 as 边界事件2
    participant A as 主活动
    
    G->>B1: 注册事件监听
    G->>B2: 注册事件监听
    A->>A: 执行主活动
    Note over B1,B2: 等待事件触发
    
    alt 事件1触发
        B1->>G: 事件发生
        G->>B2: 取消监听
        G->>流程: 继续路径1
    else 事件2触发
        B2->>G: 事件发生
        G->>B1: 取消监听
        G->>流程: 继续路径2
    end

中断与非中断边界事件

Flowable支持两种类型的边界事件:

中断边界事件

中断边界事件会取消当前活动的执行:

public class BoundaryEventActivityBehavior extends AbstractBpmnActivityBehavior {
    public void setInterrupting(boolean interrupting) {
        this.interrupting = interrupting;
    }
    
    @Override
    public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
        if (interrupting) {
            // 中断当前活动
            execution.getCurrentFlowElement().getBehavior().interrupt(execution);
        }
        // 执行边界事件处理逻辑
    }
}

非中断边界事件

非中断边界事件允许主活动继续执行,同时处理边界事件:

特性 中断边界事件 非中断边界事件
活动状态 立即终止 继续执行
事件处理 独占式处理 并行处理
适用场景 错误处理、超时 通知、日志记录

高级边界事件模式

1. 条件边界事件

BoundaryConditionalEventActivityBehavior处理基于条件的边界事件:

public class BoundaryConditionalEventActivityBehavior extends BoundaryEventActivityBehavior {
    @Override
    public void execute(DelegateExecution execution) {
        // 评估条件表达式
        // 条件满足时触发事件
    }
}

2. 补偿边界事件

补偿边界事件用于处理事务回滚和补偿逻辑:

public class BoundaryCompensateEventActivityBehavior extends BoundaryEventActivityBehavior {
    @Override
    public void execute(DelegateExecution execution) {
        // 设置补偿处理器
    }
    
    @Override
    public void trigger(DelegateExecution execution, String triggerName, Object triggerData) {
        // 执行补偿操作
    }
}

最佳实践与性能考虑

在使用网关和边界事件时,应考虑以下最佳实践:

  1. 网关选择策略

    • 简单决策使用排他网关
    • 并行处理使用并行网关
    • 复杂条件逻辑使用包容网关
  2. 边界事件优化

    • 避免过多嵌套边界事件
    • 使用非中断事件减少流程中断
    • 合理设置定时器超时时间
  3. 性能考虑

    • 网关条件表达式应保持简单
    • 边界事件监听器应高效处理
    • 避免在热点路径使用复杂事件处理

Flowable的网关和边界事件机制提供了强大的流程控制能力,通过合理使用这些组件,可以构建出既灵活又高效的业务流程解决方案。

Flowable BPMN引擎提供了企业级业务流程管理所需的完整功能体系。从BPMN 2.0标准流程建模到流程定义部署与版本管理,从流程实例启动机制到网关与边界事件处理,Flowable展现了强大的流程控制能力和灵活性。通过合理的网关选择策略、边界事件优化以及性能考虑,开发者可以构建出高效、可靠、易维护的业务流程管理系统。Flowable的多引擎集成能力使其成为复杂企业应用场景的理想选择,为数字化转型提供了坚实的技术基础。

登录后查看全文
热门项目推荐
相关项目推荐