
3.1 流程资源概述
本节主要讲解流程资源部署及其相关源码,包含如何部署、部署到何地、部署的流程资源怎么进行删除和更新操作、如何选择最优部署方案等,通常所说的流程资源包含如下。
(1)流程文档:流程文档的扩展名一般为bpmn20.xml或者bpmn,例如shareniu. bpmn20.xml。
(2)图片:根据流程文档内容生成的图片,扩展名一般为Png。
(3)Drools规则文件:通常情况下扩展名为drl。
(4)Form表单文件:通常情况下扩展名为form。
约定
本书中如果没有特殊说明,流程资源等价于流程文档。
3.1.1 流程文档部署生命周期
在开始学习流程文档部署之前,先了解流程文档部署的生命周期,如图3-1所示。

图3-1 流程文档部署生命周期
根据图3-1,可以把流程文档部署的生命周期分为四大步骤。
(1)定义流程文档:客户端可以根据自己的业务需求定义流程文档。
(2)启动流程引擎:流程引擎启动之后会自动构造ProcessEngine实例对象,这样客户端就可以通过该实例对象获取各种各样的服务类实例对象。例如,TaskService实例对象,这一系列的服务类实例对象为客户端的操作提供便利。
(3)部署流程文档:调用流程文档部署命令进行部署,该过程只需要客户端调用部署流程文档的命令即可,流程引擎收到命令之后开始进行如下操作。
• 将流程文档中定义的元素解析为Activiti的内部表示BaseElement实例。
• 对BaseElement实例对象再次解析,进而将其转化为流程虚拟机中的ActivityImpl实例对象或者TransitionImpl实例对象,该过程非常重要,也是将BaseElement实例对象注入流程虚拟机的过程。
(4)添加缓存:以上所有步骤完成之后,缓存流程定义信息,这样后续节点运转的时候,只需从缓存中取值即可,无须再次执行以上的步骤,从而大幅提升性能,流程引擎默认开启了缓存功能,后续章节会深入讲解缓存机制。
3.1.2 DeploymentBuilder核心类
接下来详细讲解流程文档部署操作,首先明确一点,不管开发人员使用何种方式部署流程文档,最终均是通过流程引擎提供的API进行操作。流程文档的部署步骤是首先通过ProcessEngine接口的实现类获取到部署服务类RepositoryService实例对象,然后借助该实例对象中的createDeployment方法创建DeploymentBuilder实例对象,DeploymentBuilder接口的默认实现类为DeploymentBuilderImpl,经过前面的一系列步骤之后,就可以获取DeploymentBuilder类型的实例对象,然后通过该实例对象调用不同的资源部署API进行流程资源的部署操作。首先分析DeploymentBuilder接口的定义,如代码清单3-1所示。
代码清单3-1 DeploymentBuilder.java

该接口提供的方法以及重要参数说明如下。
(1)inputStream参数:流程文档最终的数据流,对应数据库ACT_GE_BYTEARRAY表中的BYTES_列。
(2)resourceName参数:资源名称,对应ACT_GE_BYTEARRAY表中的NAME_列。如果客户端没有干预部署器的初始化,则资源名称必须以.bpmn20.xml或者.bpmn作为后缀,如shareniu.bpmn20.xml,否则流程文档无法完整部署,进而导致客户端无法启用相应的流程实例(因为资源名称没有被引擎验证通过,ACT_RE_PROCDEF表中不会产生数据),关于这一点后续的源码讲解会详细阐述该内部处理机制,如果有兴趣可以尝试定义一个流程文档,然后在部署流程文档时显式指定资源名称,进而观察数据库中的数据变化。看到这里可能会有疑惑:流程文档的后缀应该是.bpmn20.xml或者.bpmn,在这里需要强调一点资源名称的后缀与流程文档的后缀名完全是两个概念,在部署流程文档时,必须确保资源名称的后缀如上所说,需要注意的是如果使用addZipInputStream方式部署流程资源,则需要确保流程文档的后缀为.bpmn20.xml或者.bpmn,因为该方式部署资源时不能显式指定资源名称,所以使用该方式部署资源时,资源名称默认为压缩包中的流程文档名称,相关实现逻辑可以跟进DeploymentBuilderImpl类中的addZipInputStream方法。
(3)addInputStream方法:使用数据流的方式部署流程资源(流程文档和流程定义图片等)。
(4)addClasspathResource方法:使用classpath方式直接读取项目中classpath目录下指定的流程资源进行部署。
(5)addZipInputStream方法:将流程资源文件(流程文档和流程定义图片等)打包部署。例如,将流程文档XML和生成的流程定义图片,一般是.Png格式(非必须)打包为.zip或者.bar格式。该方式支持多个流程资源文件一次性打包部署(批量部署)。
(6)addString方式:通过字符串方式部署流程文档。例如,定义一个流程文档之后,将文档的内容读取出来然后直接使用该方式进行部署。
(7)addBpmnModel方式:通过构造BpmnModel实例对象进行流程资源的部署。该方式比较适合开发人员自定义流程设计器,可控性和扩展性比较强。
(8)deploy方法:流程资源部署的核心方法,负责流程资源的部署。