返回介绍

18.2. 深入流程解析

发布于 2023-09-17 23:40:35 字数 2978 浏览 0 评论 0 收藏 0

BPMN 2.0 XML需要解析为Flowable的内部模型,才能在Flowable引擎中执行。部署流程时,或是在内存中找不到流程时,会从数据库中读取XML并进行解析。

BpmnParser类会为每个流程创建一个BpmnParser实例,作为解析过程的容器。解析本身很简单:引擎对于每一个BPMN 2.0元素都有一个对应的org.flowable.engine.parse.BpmnParseHandler的实例,解析器将BPMN 2.0元素类映射至BpmnParseHandler实例。默认情况下,Flowable使用BpmnParseHandler实例处理所有支持的元素,并为流程的步骤附加执行监听器,以创建历史。

可以在Flowable引擎中添加org.flowable.engine.parse.BpmnParseHandler的自定义实例。比如常见使用场景是,为特定步骤添加执行监听器,向某个事件处理队列发送事件。Flowable处理历史就使用的是这种方式。要添加这种自定义处理器,需要调整Flowable配置:

<property name="preBpmnParseHandlers">
  <list>
  <bean class="org.flowable.parsing.MyFirstBpmnParseHandler" />
  </list>
</property>

<property name="postBpmnParseHandlers">
  <list>
  <bean class="org.flowable.parsing.MySecondBpmnParseHandler" />
  <bean class="org.flowable.parsing.MyThirdBpmnParseHandler" />
  </list>
</property>

preBpmnParseHandlers参数中配置的BpmnParseHandler实例将添加在默认处理器之前。类似的,postBpmnParseHandlers中实例将添加在默认处理器之后。有时顺序会影响自定义解析处理器中包含的逻辑,需要特别注意。

org.flowable.engine.parse.BpmnParseHandler是一个简单的接口:

public interface BpmnParseHandler {

  Collection<Class>? extends BaseElement>> getHandledTypes();

  void parse(BpmnParse bpmnParse, BaseElement element);

}

getHandledTypes()方法返回该解析器处理的所有类型的集合。集合的泛型提示,可用的类型是BaseElement的子类。也可以扩展AbstractBpmnParseHandler类,并覆盖getHandledType()方法,它只返回一个类而不是一个集合。这个类也包含了一些默认解析处理器通用的辅助方法。当解析器遇到匹配该方法的返回类型的元素时,将调用这个BpmnParseHandler实例进行解析。在下面的例子里,当遇到BPMN 2.0 XML中的流程元素时,就会执行其executeParse方法(这是一个类型转换方法,替代BpmnParseHandler接口中的普通parse方法)中的逻辑。

public class TestBPMNParseHandler extends AbstractBpmnParseHandler<Process> {

  protected Class<? extends BaseElement> getHandledType() {
  return Process.class;
  }

  protected void executeParse(BpmnParse bpmnParse, Process element) {
   ..
  }

}

重要提示:在实现自定义解析处理器时,不要使用任何用于解析BPMN 2.0结构的内部类。否则会很难查找bug。安全的做法是实现BpmnParseHandler接口,或扩展内部抽象类org.flowable.engine.impl.bpmn.parser.handler.AbstractBpmnParseHandler

可以(但不常用)替换默认用于将BPMN 2.0元素解析为Flowable内部模型的BpmnParseHandler实例。可以通过下面的代码片段实现:

<property name="customDefaultBpmnParseHandlers">
  <list>
  ...
  </list>
</property>

简单的例子,强制所有服务任务都异步执行:

public class CustomUserTaskBpmnParseHandler extends ServiceTaskParseHandler {

  protected void executeParse(BpmnParse bpmnParse, ServiceTask serviceTask) {

  // 进行常规操作
  super.executeParse(bpmnParse, serviceTask);

  // 保证异步执行
  serviceTask.setAsynchronous(true);
  }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文