跳到主要内容

BPMN 流程引擎自定义配置

BPMN 自定义配置用于在流程引擎构建时接入额外的变量处理、模型解析、活动行为或校验能力。Spring Boot 应用可以通过 EngineConfigurationConfigurer<SpringProcessEngineConfiguration> 注册这类扩展。

@Bean
EngineConfigurationConfigurer<SpringProcessEngineConfiguration> processEngineConfigurer() {
return configuration -> {
// 将应用自定义的 BPMN 扩展注册到流程引擎配置中
};
}

上面的回调由 Flowable 的 Spring Boot 自动配置在流程引擎创建前调用。回调取得的是 BPMN 流程引擎的配置对象,因此其中的设置只作用于流程引擎,不会自动成为 DMN 或 CMMN 引擎的配置。

SpringProcessEngineConfiguration 的核心配置​

SpringProcessEngineConfiguration 不只有 Spring 专属选项。它继承了流程引擎通用配置,因此可以同时调整数据源与事务、流程运行、历史记录、异步作业、模型解析和扩展点。下面列出日常项目最常需要理解的配置组;实际可用项以项目引入的 Flowable 版本为准。

配置组代表配置项作用与使用时机
数据源与事务dataSource、databaseSchemaUpdate、transactionsExternallyManaged指定引擎使用的数据源、数据库 schema 更新策略,以及事务是否由外部事务管理器控制。databaseSchemaUpdate=false 在启动时检查 schema 版本但不自动升级;true 会在需要时创建或升级 schema。生产环境通常由 DBA 执行升级脚本并关闭自动更新。Spring Boot 项目优先用 spring.datasource.* 和 Flowable 的 flowable.database-schema-update 等属性,特殊集成才在配置器里调整。
历史记录historyLevel、enableHistoryCleaning、historyCleaningTimeCycleConfig控制运行数据写入历史表的详细程度及历史清理策略。常见等级为 none(不归档)、activity(流程与活动历史)、audit(额外持续同步变量和表单信息,通常为默认等级)、full(记录更多细节,开销最高)。选择前应结合审计、报表和保留期要求。
异步执行asyncExecutorActivate、asyncExecutor、asyncHistoryEnabled、asyncHistoryExecutorActivate控制作业执行器和异步历史执行器是否运行,并允许替换执行器实现或调整其线程池。要区分“流程中是否有异步作业”和“当前进程是否负责获取并执行作业”;多实例部署时还需统筹节点数量、锁定时间和数据库负载。
部署与模型解析createDiagramOnDeploy、enableSafeBpmnXml、preBpmnParseHandlers、customDefaultBpmnParseHandlers、postBpmnParseHandlers控制部署时是否生成流程图、是否启用安全 XML 处理,以及自定义解析器加入默认解析器之前、默认解析过程中或之后。解析器的阶段顺序会影响它能看到的模型状态。
变量与表达式customPreVariableTypes、customPostVariableTypes、expressionManager、expressionCacheSize、beans增加变量类型、调整 EL 表达式解析和缓存,并决定表达式中可见的 Spring Bean。自定义类型需考虑匹配优先级;暴露给表达式的 Bean 也应遵循最小权限原则。
BPMN 行为与校验activityBehaviorFactory、customServiceTaskValidator、processValidator替换特定 BPMN 活动的行为创建方式、扩展服务任务校验,或更换流程模型校验器。行为工厂影响引擎解释 BPMN 元素的方式,通常只应在明确需要改变默认执行语义时使用。
事件与委托eventListeners、typedEventListeners、customEventHandlers、flowableFunctionDelegates注册引擎事件监听器、自定义事件处理器和可供表达式调用的 Flowable 函数。监听器应保持短小;需要可靠的外部副作用时,应设计好事务提交时机、幂等和重试。
缓存与标识processDefinitionCacheLimit、processDefinitionInfoCacheLimit、idGenerator、idBlockSize调整流程定义及其信息缓存上限,或接入自定义 ID 生成器。缓存应结合流程定义数量和内存预算评估;自定义 ID 需要保证全局唯一性并适配多节点部署。

多数基础开关已有 Spring Boot 属性,优先通过配置文件管理,便于不同环境覆盖并避免在 Java 代码里重复写值。EngineConfigurationConfigurer 更适合注册自定义 Java 扩展,或配置文件难以表达的对象。下例展示 Java 配置写法;历史等级或异步开关这类会影响系统行为的选项,应由部署环境明确决定:

@Bean
EngineConfigurationConfigurer<SpringProcessEngineConfiguration> processEngineTuning() {
return configuration -> {
configuration.setCreateDiagramOnDeploy(false);
configuration.setEnableSafeBpmnXml(true);
configuration.setProcessDefinitionCacheLimit(256);
};
}

缓存值只是示例,应根据定义数量、访问频率和堆内存压测确定;安全 XML 选项也应按 Flowable 版本和模型来源要求核对。

常见扩展方向​

自定义流程变量类型​

当流程变量需要使用引擎默认类型体系之外的对象或序列化方式时,可以实现 Flowable 的变量类型扩展,并将它加入流程引擎配置。

变量类型通常需要定义类型识别、值读取与写入、持久化表示等行为。注册顺序也可能影响类型选择:如果多个类型都可能识别同一个值,应明确优先级,避免自定义类型意外覆盖内置类型,或反过来被内置类型先行匹配。

把变量类型注册到流程引擎不会自动让数据库理解新的 Java 对象。自定义序列化仍须兼顾跨版本读取、历史数据兼容、事务失败后的重试,以及数据格式升级策略。

注册时可以把自定义类型放在默认类型之前,让类型匹配先检查它:

@Bean
EngineConfigurationConfigurer<SpringProcessEngineConfiguration> invoiceVariableConfigurer(
InvoiceReferenceVariableType invoiceReferenceVariableType) {
return configuration -> configuration.setCustomPreVariableTypes(
List.of(invoiceReferenceVariableType)
);
}

这里的 InvoiceReferenceVariableType 需要实现 Flowable 的 VariableType 契约,负责类型识别、值的读写和持久化字段映射。若类型只应在默认类型未匹配时尝试,可考虑使用配置提供的后置变量类型列表。类型名与持久化格式应保持稳定,避免升级后旧流程变量无法读取。

下面用一个只保存业务编号的值对象展示该契约的基本结构。复杂对象应使用稳定的序列化格式,并为数据升级和长度限制补充处理:

public record InvoiceReference(String id) {
}

public final class InvoiceReferenceVariableType implements VariableType {

@Override
public String getTypeName() {
return "invoice-reference";
}

@Override
public boolean isAbleToStore(Object value) {
return value instanceof InvoiceReference;
}

@Override
public boolean isCachable() {
return true;
}

@Override
public void setValue(Object value, ValueFields fields) {
InvoiceReference reference = (InvoiceReference) value;
fields.setTextValue(reference.id());
}

@Override
public Object getValue(ValueFields fields) {
String id = fields.getTextValue();
return id == null ? null : new InvoiceReference(id);
}
}

将对象编码进单个文本字段只适合短且稳定的标识值;若存储完整对象,应评估字段长度、加密、版本兼容和敏感数据策略。

BPMN 模型解析处理器​

解析处理器在 BPMN 资源部署和解析时参与模型处理,可用于识别指定元素、检查约束或为模型元素附加扩展行为。它的工作时机与流程实例运行时不同:解析器处理的是已部署的模型,通常不会在每次执行任务时重新运行。

设计解析处理器时,应将处理限制在明确的元素类型或命名空间,并考虑同一资源重复部署、模型升级和解析顺序。需要拒绝无效模型时,应通过清楚的校验错误说明具体元素和原因。

例如,可以在默认处理器之后检查服务任务上的应用自定义扩展属性:

@Bean
EngineConfigurationConfigurer<SpringProcessEngineConfiguration> auditTaskParserConfigurer(
AuditTaskParseHandler auditTaskParseHandler) {
return configuration -> configuration.setPostBpmnParseHandlers(
List.of(auditTaskParseHandler)
);
}

AuditTaskParseHandler 应实现 BpmnParseHandler,在 getHandledTypes() 中声明它关心的 BPMN 元素,并在 parse(...) 中处理匹配元素。放在解析器之后,适合读取默认解析已经生成的结构;如果扩展必须先影响默认解析,应使用前置处理器。不要把覆盖默认处理器和追加自定义处理器混为一谈。

处理器的最小结构如下。示例仅匹配服务任务,并读取应用命名空间下的 audit 属性;实际项目可在此处执行静态校验或记录扩展元数据:

public final class AuditTaskParseHandler implements BpmnParseHandler {

private static final String APP_NAMESPACE = "https://example.org/workflow";

@Override
public Collection<Class<? extends BaseElement>> getHandledTypes() {
return Set.of(ServiceTask.class);
}

@Override
public void parse(BpmnParse bpmnParse, BaseElement element) {
ServiceTask serviceTask = (ServiceTask) element;
String auditMode = serviceTask.getAttributeValue(APP_NAMESPACE, "audit");

if ("required".equals(auditMode)) {
// 在模型部署阶段检查或记录这个服务任务的扩展配置。
}
}
}

此类代码需要导入 BpmnParseHandler、BpmnParse、BaseElement、ServiceTask、Collection 和 Set。解析处理器在部署阶段运行,不要在其中执行流程运行时的业务副作用。

活动行为工厂​

活动行为工厂负责为模型活动创建运行时行为。它适用于在标准活动之外增加受控的执行逻辑,或替换某类活动的默认行为。

工厂通常需要与流程引擎运行时环境协作,例如表达式解析、委托实例创建和变量作用域。扩展行为应保持 Flowable 的命令上下文与事务边界,不要绕过引擎服务直接修改内部持久化对象。

配置工厂时,通常继承默认工厂并只覆盖明确需要改变的行为:

@Bean
EngineConfigurationConfigurer<SpringProcessEngineConfiguration> activityFactoryConfigurer(
AuditActivityBehaviorFactory auditActivityBehaviorFactory) {
return configuration -> configuration.setActivityBehaviorFactory(
auditActivityBehaviorFactory
);
}

工厂实现应尽量只对特定活动返回自定义行为,其余活动继续交给默认工厂处理。改变标准网关、事件或任务的语义可能让流程不再符合 BPMN 预期;如果需求只是新增业务步骤,优先考虑服务任务委托,而不是替换标准活动行为。

服务任务校验​

如果应用需要在部署或模型校验阶段检查服务任务的配置,可以注册自定义校验逻辑。校验规则应与实际执行规则保持一致,例如校验模型中声明的委托类型、必需字段或扩展属性。

校验失败应尽早提供可定位的信息,使建模人员能够在发布前修正模型;校验器不适合承载依赖运行时数据的业务判断。

将应用校验器接入配置的形式如下:

@Bean
EngineConfigurationConfigurer<SpringProcessEngineConfiguration> serviceTaskValidationConfigurer(
DomainServiceTaskValidator domainServiceTaskValidator) {
return configuration -> configuration.setCustomServiceTaskValidator(
domainServiceTaskValidator
);
}

DomainServiceTaskValidator 应实现当前 Flowable 版本要求的服务任务校验接口。校验器可检查模型静态信息,例如委托配置或必需扩展属性;外部系统状态、用户权限等运行期信息应留给运行时业务逻辑处理。

机制与注意事项​

扩展对象由应用创建并注册到流程引擎配置。Flowable 在引擎初始化期间装配这些扩展,后续解析流程定义或执行流程实例时再按扩展职责调用它们。因此,注册和对象生命周期应与应用中的 Spring Bean、依赖注入和引擎生命周期相匹配。

  • 确认流程引擎使用的是 Spring Boot 自动配置管理的实例,并且配置器确实注册为 Spring Bean。
  • 只将需要参与引擎初始化的注册放在配置器中;不要在回调中启动消息消费、调度任务等长期运行的工作。
  • 用实际 BPMN 模型覆盖部署解析、校验错误、流程执行、异常和重试场景。
  • 如果自定义类型或行为影响已部署模型,升级时评估正在运行的流程实例和历史变量的兼容性。

更多扩展时机说明见自定义配置机制总览。

参考资料​