一、业务归档
要发布流程,流程必须被包裹进一个业务归档中。对一个Activiti引擎来说,一个业务归档是部署的一个单元。一个业务归档等同于一个zip文件。它能包含BPMN2.0 流程信息,任务表单,规则和任何其他文件类型。大体上,一个业务归档包含了资源命名的集合。
当一个业务归档发布的时候,要扫描归档文件中的.bpmn20.xml 或者 .bpmn。每一个文件都会被解析并且都可能包含多个流程定义。
注:
目前在业务归档中的Java类,将不会被加入到classpath。在业务归档中,所有的用在流程定义中的自定义类,为了运行流程,应存放在activiti引擎的classpath。
二、编程部署
从zip文件中部署一个业务归档,可以这样做:
String barFileName = "path/to/process-one.bar";
ZipInputStream inputStream = new ZipInputStream(new FileInputStream(barFileName));
repositoryService.createDeployment()
.name("process-one.bar")
.addZipInputStream(inputStream)
.deploy();
三、用Activiti Explorer部署
Activiti Explorer应用允许通过应用的用户界面,上传bar文件。选择manage选项卡并且点击部署。
会弹出一个window窗口,允许你从本地选择一个文件,或者你能从本地拖拽到设计区域
四、外部资源
流程定义活在Activiti数据库中。当用Activiti配置文件中服务任务或者执行监听或者Spring实体的时候,这些流程定义能参考委托类。对于所有的能执行流程定义的流程引擎,这些类和Spring的配置文件都是可用的。
java类
当一个流程实例开始的时候,所有用在你的流程中的自定义类都应该存放在引擎的classpath中。
然而,经过一个业务归档的部署,这些类都不会被存放到classpath中。这意味着当你用ant部署一个新的业务归档的时候,你的委托类不会到classpath中。
当你正在安装demo,并且你不想添加你的自定义类,你应该把一个包含你的类的jar包添加到activiti-explorer或者activiti-rest中的lib中。不要忘记要包含进你的类的依赖jar.另外,你也能在tomcat的lib路径下包含进你的依赖类。
从一个流程中用Spring实体
对执行流程定义的引擎来说,在表达式或者脚本中用的Spring实体,这些实体都是可用的。如果你正在编译你自己的应用,并且你在上下文中配置了你的流程引擎,这些都是简单的。
创建一个单一应用
不用确保所有的流程引擎在他们的classpath中拥有所有的委托类,并且有正确的Spring配置,而是你要包含Activiti rest webapp到你自己的webapp中,这样才会有一个单一的流程引擎。
五、流程定义的版本
BPMN没有一个版本的概念。这样的确是好的,因为可执行的BPMN流程文件会存活在系统知识库版本控制中,作为你开发的工程的一部分。流程定义的版本通过部署来创建。通过部署,Activiti会给ProcessDefinition签名一个版本,在保存到ActivitiDB之前。
对于在业务归档中的每一个流程定义会执行下面的步骤来初始化一个key,version,name和id:
-
- xml文件中的流程定义的id属性是被用于作为流程定义的key属性。
- xml文件中的流程定义的name属性是被用于作为流程定义的name属性。如果name属性没有被指定,那么id属性被作为name属性。
- 一个有特殊key的流程第一次被部署,版本号为1。对于拥有同样key的流程定义,所有之后被部署的,版本号会递增1。key属性被用于区分不同的流程定义。
- id属性被设置成 {processDefinitionKey}:{processDefinitionVersion}:{generated-id},在一个集群环境中的流程定义缓存中,这里的generated-id是一个唯一的数字,为了保证流程id的唯一性。
例如:
<definitions id="myDefinitions" >
<process id="myProcess" name="My important process" >
...
当部署这个流程定义的时候,在数据库中流程定义看起来会是这样:
Table 6.1.
myProcess:1:676 | myProcess | My important process | 1 |
假设我们现在部署了一个同样流程的升级版本,但是流程定义的id属性保持不变。流程定义的表现在变成这样:
Table 6.2.
myProcess:1:676 | myProcess | My important process | 1 |
myProcess:2:870 | myProcess | My important process | 2 |
当 runtimeService.startProcessInstanceByKey("myProcess")调用的时候,它会用版本2的流程定义作为流程定义的最新版本。
当我们创建第二个流程作为下面定义的并且发布到Activiti,表中会多添加一行。
<definitions id="myNewDefinitions" >
<process id="myNewProcess" name="My important process" >
...
现在的表会是这样:
Table 6.3.
myProcess:1:676 | myProcess | My important process | 1 |
myProcess:2:870 | myProcess | My important process | 2 |
myNewProcess:1:1033 | myNewProcess | My important process | 1 |
注意新流程的key与我们第一个流程的key是不同的。即使名字相同,Activiti在区分流程的时候,只考虑id属性。前面的新流程会被部署为版本1。
六、提供一个流程图
一个流程图的图片能添加到一个部署包中。这个图片会被存放在Activiti的知识库中,并且通过API方法能够访问。这个图片也被用于在Activiti Explorer中查看流程。
假设在我们的classpath中,我们有一个流程
org/activiti/expenseProcess.bpmn20.xml。这个流程的key为‘expense’。下面为流程图的图片命名约定。
- 如果在部署包中存在一个图片资源, 并且有一个名称为BPMN2.0的xml文件的名称,再串联流程定义的key,并且有图片的格式,那么这个图片就作为流程 图。在我们的例子中,会是 org/activiti/expenseProcess.expense.png(或者.jpg/gif)。如果你有多个图片在一个BPMN2.0的xml文件,那么这种命名方式最有意义。每一个流程图图片都会在它的名字中有流程的key。
- 如果这样的图片不存在,那么在部署包中名字匹配BPMN2.0 XML文件的图片资源会被搜索到。在我们的例子中会是 org/activiti/expenseProcess.png。注:这意味着在同样的BPMN2.0文件中定义的每一个流程定义都会有同样的流程图图片。如果在每一个BPMN2.0 XML文件中都只有一个流程定义,这显然不会有任何问题。
repositoryService.createDeployment()
.name("expense-process.bar")
.addClasspathResource("org/activiti/expenseProcess.bpmn20.xml")
.addClasspathResource("org/activiti/expenseProcess.png")
.deploy();
这个图片资源会通过API被检索到:
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("expense")
.singleResult();
String diagramResourceName = processDefinition.getDiagramResourceName();
InputStream imageStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), diagramResourceName);
七、生成一个流程图
如果在部署包中不提供一个流程图,如果流程定义包含必要的图交换信息,Activiti 引擎会生成一个流程图。
如果,基于某种原因,在部署的时候,你不想或者也没有必要生成流程图,那么在流程引擎配置的时候,
isCreateDiagramOnDeploy
这个属性可以被设置。
<property name="createDiagramOnDeploy" value="false" />
现在就不会生成流程图了。
八、部署类别
部署包和流程定义都会有用户定义的类别。流程定义类别的值会在BPMN文件中被初始化:
<definitions ... targetNamespace="yourCategory" ...
也能通过API来指定部署的类别:
repositoryService .createDeployment() .category("yourCategory") ... .deploy();