ProcessDefinition,流程定义:
一个流程的步骤说明。如一个请假流程、报销流程、借款流程等,是一个规则。
例:
ProcessInstance,流程实例:
代表流程定义的一次执行。如张三昨天按请假流程请了一次假。一个流程实例包括了所有运行阶段, 其中最典型的属性就是跟踪当前节点的指针。
Execution,执行:
一般情况下,一个流程实例是一个执行树的根节点。
使用树状结构的原因在于,这一概念只有一条执行路径, 使用起来更简单。 业务API不需要了解流程实例和执行之间功能的区别。因此, API里只有一个执行类型来引用流程实例和执行。
假设汇款和存档可以同时执行,那么主流程实例就包含了2个用来跟踪状态的子节点:
Interacting with jBPM occurs through services. Theservice interfaces can be obtained from the ProcessEngine which is build from aConfiguration. A ProcessEngine is thread safe and can be stored in astatic member field.
使用默认的配置文件(jbpm.cfg.xml)生成Configuration并构建ProcessEngine:
ProcessEngineprocessEngine = new Configuration()
.buildProcessEngine();
或是使用如下代码获取使用默认配置文件的、单例的ProcessEngine对象:
ProcessEngineprocessEngine = Configuration.getProcessEngine();
或是使用指定的配置文件(要放到classPath下):
ProcessEngineprocessEngine = new Configuration()
.setResource("my-own-configuration-file.xml")
.buildProcessEngine();
jBPM所有的操作都是通过Service完成的,以下是获取Service的方式:
RepositoryService repositoryService = processEngine
.getRepositoryService();
ExecutionService executionService = processEngine
.getExecutionService();
TaskService taskService = processEngine
.getTaskService();
HistoryService historyService = processEngine
.getHistoryService();
ManagementService managementService = processEngine
.getManagementService();
各个Service的作用:
RepositoryService |
管理流程定义 |
ExecutionService |
管理执行的,包括启动、推进、删除Execution等操作 |
TaskService |
管理任务的 |
HistoryService |
历史管理(执行完的数据管理,主要是查询) |
IdentityService |
jBPM的用户、组管理 |
ManagementService |
|
方法调用链
每一个方法都是流程有关的一个业务操作,默认是一个独立的事务。
功能说明 |
相应的查询API |
查询“流程定义” |
ProcessDefinitionQuery processDefinitionQuery = processEngine.getRepositoryService() .createProcessDefinitionQuery(); |
查询“执行对象” (流程实例) |
ProcessInstanceQuery processInstanceQuery = processEngine.getExecutionService() // .createProcessInstanceQuery(); |
查询“任务” |
TaskQuery taskQuery = // processEngine.getTaskService()// .createTaskQuery(); |
查询“执行历史” (流程实例历史) |
HistoryProcessInstanceQuery historyProcessInstanceQuery = processEngine.getHistoryService() .createHistoryProcessInstanceQuery(); |
查询“任务历史” |
HistoryTaskQuery historyTaskQuery = processEngine.getHistoryService() .createHistoryTaskQuery(); |
以上列出的Query对象有:
1. ProcessDefinitionQuery
2. ProcessInstanceQuery
3. TaskQuery
4. HistoryProcessInstanceQuery
5. HistoryTaskQuery
这些Query对象的使用方法都是一致的,如下所示:
1, 添加过滤条件:调用其中的有关方法指定条件即可。如:
a) processDefinitionQuery.processDefinitionKey("请假")是指定查询key为”请假”的流程定义;
b) taskQuery.assignee("张三")是指定办理人为”张三”的任务。
2, 添加排序条件:
a) 调用 xxQuery.orderAsc(property),表示按某属性升序排列
b) 调用 xxQuery.orderDesc(property),表示按某属性降序排列
c) 可指定多个排序条件,就是代表第1顺序,第2顺序…等。
d) 属性名在各自的Query对象(接口)中有常量定义,如:
i. ProcessDefinitionQuery.PROPERTY_ID
ii. ProcessDefinitionQuery.PROPERTY_KEY
iii. TaskQuery.PROPERTY_NAME
iv. TaskQuery.PROPERTY_ASSIGNEE
3, 指定分页有关信息:
a) 调用方法xxQuery.page(firstResult, maxResults);
b) 这是指定first与max的值(就是Hibernate中的Query.setFirstResult()与Query.setMaxResults())
c) 如果没有调用这个方法,代表要查询出符合条件的所有记录。
4, 查询得到结果:
a) 调用方法xxQuery.list();表示查询列表
b) 调用方法 xxQuery.uniqueResult(); 表示查询唯一的结果
c) 调用方法xxQuery.count();表示查询符合条件的记录数量
没有更新功能
注意区分Deployment与ProcessDefinition
String deploymentId = processEngine.getRepositoryService()
.createDeployment()
.addResourceFromClasspath("process/test.jpdl.xml")
.addResourceFromClasspath("process/test.png")
.deploy();
String deploymentId = processEngine.getRepositoryService()
.createDeployment()
.addResourcesFromZipInputStream(zipInputStream)
.deploy();
1, .addResourceFromClasspath(resource);可以调用多次以添加多个文件。文件重复添加也不会报错。
2, .addResourceFromInputStream(resourceName,inputStream)添加一个文件(使用InputStream)
3, .addResourcesFromZipInputStream(zipInputStream)添加多个文件,里面也可以有文件夹。
4, 以上方法可以在一起调用。
repositoryService.deleteDeployment(deploymentId);
repositoryService.deleteDeploymentCascade(deploymentId);
关联:关联的流程实例,就是流程定义中执行过的那些实例【已经放到了历史表中,级联删除的就是同时删除那些执行过了的实例】,
RepositoryService.createProcessDefinitionQuery()
// 1,构建查询
ProcessDefinitionQuery pdQuery= processEngine.getRepositoryService()
.createProcessDefinitionQuery()//
.orderAsc(ProcessDefinitionQuery.PROPERTY_NAME)//
.orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION);
// 2,查询出总数量与数据列表
long count = pdQuery.count();
List<ProcessDefinition>list = pdQuery.page(0, 100).list();// 分页:取出前100条记录
// 3,显示结果
System.out.println(count);
for (ProcessDefinition pd : list) {
System.out.println("id=" + pd.getId()//
+ ",deploymentId=" + pd.getDeploymentId()//
+ ",name=" + pd.getName()//
+ ",version=" + pd.getVersion()//
+ ",key=" + pd.getKey()); //
}
// 1,查询,按version升序排序,则最大版本排在最后面
List<ProcessDefinition>all = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)
.list();
// 2,过滤出所有不同Key的最新版本(因为最大版本在最后面)
Map<String,ProcessDefinition> map = new HashMap<String, ProcessDefinition>(); // map的key是流程定义的key,map的vlaue是流程定义对象
for (ProcessDefinition pd : all) {
map.put(pd.getKey(), pd);
}
Collection<ProcessDefinition>result = map.values();
// 3,显示结果
for (ProcessDefinition pd : result) {
System.out.println("deploymentId=" + pd.getDeploymentId()//
+ ",\tid=" + pd.getId()// 流程定义的id,格式:{key}-{version}
+ ",\tname=" + pd.getName()
+ ",\tkey=" + pd.getKey()
+ ",\tversion=" + pd.getVersion());
}
// 资源的名称,就是 jbpm4_lob 表中的 NAME_ 列表值
String deploymentId = "90001";
String resourceName = "test.png";
InputStream in = processEngine.getRepositoryService()
.getResourceAsStream(deploymentId, resourceName);
String processDefinitionId = "test-1"; // 流程定义的id
String activityName = "start1"; // 活动的名称
ActivityCoordinates c = processEngine.getRepositoryService()
.getActivityCoordinates(processDefinitionId,activityName);
System.out.println("x=" + c.getX()
+ ",y=" + c.getY()
+ ",width=" + c.getWidth()
+ ",height=" + c.getHeight());
流程定义管理
package com.xsy.jbpm.b_processdefinition;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipInputStream;
import org.jbpm.api.Configuration;
import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessDefinitionQuery;
import org.jbpm.api.ProcessEngine;
import org.junit.Test;
publicclass ProcessDefinitionTest {
// 使用指定的配置文件生成ProcessEngine对象
// private ProcessEngine processEngine =new Configuration().setResource("jbpm.cfg.xml").buildProcessEngine();
// 使用默认的配置文件生成ProcessEngine对象(jbpm.cfg.xml)
// private ProcessEngine processEngine =new Configuration().buildProcessEngine();
// 获取单例的ProcessEngine对象(使用的是默认的配置文件:jbpm.cfg.xml,使用的是懒汉单例
private ProcessEngine processEngine = Configuration.getProcessEngine();
// 部署(添加)
// jbpm4_deployment主部署对象表
// jbpm4_lob资源文件表(保存png和xml)
// jbpm4_deployprop部署的时候事先读取一遍文件获取key等信息,放入这个表,供查询使用
@Test
publicvoid testDeploy() throws Exception {
// NewDeployment deployment =processEngine.getRepositoryService().createDeployment();
//deployment.addResourceFromClasspath("helloworld/helloworld.jpdl.xml");
// deployment.addResourceFromClasspath("helloworld/helloworld.png");
// deployment.deploy();
String deploymentId = processEngine.getRepositoryService()//
.createDeployment()//
.addResourceFromClasspath("helloworld/helloworld.jpdl.xml")//
.addResourceFromClasspath("helloworld/helloworld.png")//
.deploy();
System.out.println("部署成功:deploymentId = " + deploymentId);
}
JBPM4中所有的xxId都是String型的
deploymentId
processDefinitionId
processInstanceId
ExecutionId
taskId
...
// 部署(zip)
@Test
publicvoid testDeploy_zip() throws Exception {
// 找到zip
InputStream in = this.getClass().getClassLoader().getResourceAsStream("first.zip");
ZipInputStream zipInputStream = new ZipInputStream(in);
// 部署
String deploymentId = processEngine.getRepositoryService()//
.createDeployment()//
.addResourcesFromZipInputStream(zipInputStream)//
.deploy();
System.out.println("部署成功:deploymentId = " + deploymentId);
}
// 查询所有
@Test
publicvoid findAll() throws Exception {
// 查询
List<ProcessDefinition> list = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
// 过滤条件
//.processDefinitionKey("")//
//.processDefinitionNameLike("%xx%")//
// 排序条件
//.orderAsc(ProcessDefinitionQuery.PROPERTY_KEY)//
//.orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION)//
// 执行查询
// .uniqueResult();
// .count();
//.page(firstResult, maxResults)//
.list();
// 显示
// 流程定义是不对应表的,由部署对象中的xml解析得到
for (ProcessDefinition pd : list) {
System.out.println("id=" + pd.getId()// 格式为:{key}-{version},用于唯一标识流程定义
+ ",name=" + pd.getName()// 流程定义的名称,jpdl.xml中根元素的name属性的值
+ ",key=" + pd.getKey()// 流程定义的key,jpdl.xml中根元素的key属性的值,默认是name属性
+ ",version=" + pd.getVersion()// 自动生成的,同一个名称的第一个为1,以后的自动+1
+ ",deploymentId=" + pd.getDeploymentId()); // 所选的部署对像
}
}
Deployment 部署对象
说明:
一次部署的多个文件的信息,通常是有jpdl.xml 与 png 这两个文件。
对应的表:
jbpm4_deployment
jbpm4_lob
jbpm4_deployprop
ProcessDefinition 流程定义
说明:
解析 jpdl.xml 后得到的流程的信息,其中包含流程中所有的环节与每个环节的详细信息等。
// 查询所有最新版本的流程定义
@Test
publicvoid findAllLatestVersions() throws Exception {
// 查询所有,让最新的版本都排到最后
List<ProcessDefinition> all = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)//
.list();
// 利用Map过滤出所有最新的版本
Map<String, ProcessDefinition> map = new HashMap<String,ProcessDefinition>();
for (ProcessDefinition pd : all) {
map.put(pd.getKey(), pd);//针对每一种key找到最新的覆盖以前的(key作为键,同一种流程定义的key是一样的,但是version不一样,还在后面所以。。。)
}
// 显示
for (ProcessDefinition pd : map.values()) {
System.out.println("id=" + pd.getId()// 格式为:{key}-{version},用于唯一标识流程定义
+ ",name=" + pd.getName()// 流程定义的名称,jpdl.xml中根元素的name属性的值
+ ",key=" + pd.getKey()// 流程定义的key,jpdl.xml中根元素的key属性的值,默认是name属性
+ ", version=" + pd.getVersion()// 自动生成的,同一个名称的第一个为1,以后的自动+1
+ ",deploymentId=" + pd.getDeploymentId()); // 所选的部署对像
}
} }
@Test
publicvoid deleteById() throws Exception {
String deploymentId = "90001";
// // 删除指定的部署对象(流程定义),如果有关联的执行信息,就会报错
// processEngine.getRepositoryService().deleteDeployment(deploymentId);
// 删除指定的部署对象(流程定义),如果有关联的执行信息,会被同时删除
processEngine.getRepositoryService().deleteDeploymentCascade(deploymentId);
}
// 删除指定key的所有版本的流程定义
@Test
publicvoid deleteByKey() throws Exception {
// 查询出指定key的所有版本的流程定义
List<ProcessDefinition> list = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
.processDefinitionKey("helloworld")//
.list();
// 一一删除
for (ProcessDefinition pd : list) {
processEngine.getRepositoryService().deleteDeploymentCascade(pd.getDeploymentId());
}
}
// 查看流程图(xxx.png)
@Test
publicvoid getImageResource() throws Exception {
String deploymentId = "90001";
String resourceName = "helloworld/helloworld.png";
// 获取指定部署对象中的所有资源的名称
Set<String> names = processEngine.getRepositoryService().getResourceNames(deploymentId);
System.out.println("所有的资源名称:");
for (String name : names) {
System.out.println("\t" + name);
}
// 获取指定部署对象中的指下资源的内容
InputStream in = processEngine.getRepositoryService().getResourceAsStream(deploymentId,resourceName);
// 保存到e盘
OutputStream out = new FileOutputStream("e:/process.png");
for (int b = -1; (b = in.read()) != -1;) {
out.write(b);
}
in.close();
out.close();
}