Activiti学习笔记第五篇:管理流程定义
1.设计流程定义文档
1.1流程图
1.2 bpmn文件
. BPMN 2.0根节点是definitions节点。 这个元素中,可以定义多个流程定义(不过我们建议每个文件只包含一个流程定义, 可以简化开发过程中的维护难度)。 一个空的流程定义看起来像下面这样。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的声明。 targetNamespace可以是任意值,它用来对流程实例进行分类。
说明:流程定义文档有两部分组成:
- bpmn文件
流程规则文件。在部署后,每次系统启动时都会被解析,把内容封装成流程定义放入项目缓存中。Activiti框架结合这个xml文件自动管理流程,流程的执行就是按照bpmn文件定义的规则执行的,bpmn文件是给计算机执行用的。 - 展示流程图的图片
在系统里需要展示流程的进展图片,图片是给用户看的。
2. 部署流程定义(classpath路径加载文件)
@Test
public void deploy() throws Exception{
// 获取仓库服务,从类路径下完成部署
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.name("请假流程名称")
.addClasspathResource("diagrams/Leave1.bpmn")// 添加定义的规则文件
.addClasspathResource("diagrams/Leave1.png")
.deploy();//完成发布
System.out.println(deployment.getId()+" "+deployment.getName();
}
说明:
- 先获取流程引擎对象:在创建时会自动加载classpath下的activiti.cfg.xml
// 创建流程引擎对象
private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- 首先获得默认的流程引擎,通过流程引擎获取了一个RepositoryService对象(仓库对象)
- 由仓库的服务对象产生一个部署对象配置对象,用来封装部署操作的相关配置。
- 这是一个链式编程,在部署配置对象中设置显示名,上传流程定义规则文件
- 向数据库表中存放流程定义的规则信息。
- 这一步在数据库中将操作三张表:
a) act_re_deployment(部署对象表)
存放流程定义的显示名和部署时间,每部署一次增加一条记录
b) act_re_procdef(流程定义表)
存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。
注意:当流程定义的key相同的情况下,使用的是版本升级
c) act_ge_bytearray(资源文件表)
存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片的(如果部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都是以二进制形式存储在数据库中。
3. 部署流程定义(zip格式文件)
@Test
public void deployZIP() throws Exception {
// 获得上传文件的输入流程
InputStream in = this.getClass().getClassLoader().getResourceAsStram("diagrams/Leave.zip");
ZipInputStream zipInputStream = new ZipInputStream(in);
// 获取仓库服务,从类路径下完成部署
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.name("请假流程")// 添加部署规则显示别名
.addZipInputStream(zipInputStream) //使用zip的输入流完成部署
.deploy();//完成发布
System.out.println(deployment.getId()+" "+deployment.getName());
}
将压缩成zip格式的文件,使用zip的输入流用作部署流程定义
4. 查看流程定义
查询流程定义的信息
/**
* 2.查看流程定义
* id: {key}:{version}:{随机值}
* name: 对应流程文件process节点的name属性
* key: 对应流程文件process节点的id属性
* version: 发布时自动生成的。如果是第一发布的流程,veresion默认从1开始;
* 如果当前流程引擎中已存在相同key的流程,则找到当前key对应的最高版本号,在最高版本号上加1
* /
@Test
public void queryProcessDefinition() throws Exception {
// 获取仓库服务对象,使用版本的升序排列,查询列表
List<ProcessDefinition> pdList = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
// 添加查询条件
//.processDefinitionName(processDefinitionName)
//.processDefinitionId(processDefinitionId)
//.processDefinitionKey(processDefinitionKey)
//排序
.orderByProcessDefinitionVersion().asc()
//查询的结果集
//.count()//返回结果集的数量
//.listPage(firstResult, maxResults)//分页查询
//.singleResult()//唯一结果集
.list();//总的结果集数量
//遍历集合,查看内容
for(ProcessDefinition pd : pdList) {
System.out.println("id:"+pd.getId());
System.out.println("name:"+pd.getName());
System.out.println("key:"+pd.getKey());
System.out.println("version:"+pd.getVersion());
System.out.println("resourceName:"+pd.getDiagramResourceName());
System.out.println("*******************");
}
}
结果:
再部署一次运行结果为:
可以看到流程定义的key值相同的情况下,版本是从1开始逐次升级的
流程定义的Id是【key:版本:生成ID】
说明:
- 流程定义和部署对象相关的Service都是RepositoryService。
- 创建流程定义查询对象,可以在ProcessDefinitionQuery上设置查询的相关参数
- 调用ProcessDefinitionQuery对象的list方法,执行查询,获得符合条件的流程定义列表
- 由运行结果可以看出:
Key和Name的值为:bpmn文件process节点的id和name的属性值<process id="LeaveFlow" name="请假流程" isExecutable="true">
- key属性被用来区别不同的流程定义。
- 带有特定key的流程定义第一次部署时,version为1。之后每次部署都会在当前最高版本号上加1
- Id的值的生成规则为:{processDefinitionKey}:{processDefinitionVersion}:{generated-id}, 这里的generated-id是一个自动生成的唯一的数字
- 重复部署一次,deploymentId的值以一定的形式变化
规则act_ge_property表生成
5. 删除流程定义
删除部署到activiti中的流程定义。
// 3.删除流程
@Test
public void deleteDeployment() throws Exception {
// 删除发布信息
String deploymentId = "1";
// 获取仓库服务对象
RepositoryService repositoryService = processEngine.getRepositoryService();
// 普通删除,如果当前规则下有正在执行的流程则抛出异常
// repositoryService.deleteDeployment(deploymentId);
// 级联删除,会删除和当前规则相关的所有信息,正执行的信息,也包括历史信息
// 相当于:repositoryService.deleteDeployment(deploymentId, true);
}
说明:
- 因为删除的是流程定义,而流程定义的部署是属于仓库服务的,所以应该先得到RepositoryService
- 如果该流程定义下没有正在运行的流程,则可以用普通删除。如果是有关联的信息,用级联删除。项目开发中使用级联删除的情况比较多,删除操作一般只开放给超级管理员使用。
6. 获取流程定义文档的资源(查看流程图附件)
查询出流程定义文档。主要查的是图片,用于显示流程用。
// 4.查看流程附件(查看流程图片)
@Test
public void viewImage() throws Exception {
// 从仓库中 找需要展示的文件
String deploymentId = "401";
List<String> name = processEngine.getRepositoryService()
.getDeploymentResourceNames(deloymentId);
String imageName = null;
for(String name : names) {
System.out.println("name:"+name);
if(name.indexof(".png)>=0){
imageName = name;
}
}
System.out.println("imageName:"+imageName);
if(imageName != null){
//System.out.println(imageName);
File f = new File("e:/"+imageName);
// 通过部署ID和文件名称得到文件的输入流
InputStream in = processEngine.getRepositorySErvice()
.getResourceAsStream(deploymentId, imageName);
FileUtils.copyInputStreamToFile(in, f);
}
}
说明:
- deploymentId为流程部署ID
- resourceName为act_ge_bytearray表中NAME_列的值
- 使用repositoryService的getDeploymentResourceNames方法可以获取指定部署下得所有文件的名称
- 使用repositoryService的getResourceAsStream方法传入部署ID和资源图片名称可以获取部署下指定名称文件的输入流
- 最后的有关IO流的操作,使用FileUtils工具的copyInputStreamToFile方法完成流程流程到文件的拷贝,将资源文件以流的形式输出到指定文件夹下
7. 附加功能:查询最新版本的流程定义
/**查看最细版本的流程定义*/
@Test
public void queryAllLatestVersions() throwsException{
// 查询,把最大的版本都排到后面
List<ProcessDefinition> list = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.orderByProcessDefinitionVersion().asc()
.list();
// 过滤出最新的版本
Map<String, ProcessDefinition> map = new LinkedHashMap<String, ProcessDefinition>();
for(ProcessDefinition pd : list) {
map.put(pd.getKey(), pd);
}
// 显示
for(ProcessDefinition pd : map.values()){
System.our.println("id:"+pd.getId()//格式:{key}-{version}
+",name:"+pd.getName()// .jpdl.xml根元素的name属性值
+",key:"+pd.getKey()//.jpdl.xml根元素的key属性的值,如果不写,默认name属性的值
+",version:"+pd.getVersion()//默认自动维护,第1个是1,以后相同的key的都会自动加1
+",deploymentId:"+pd.getDeploymentId());//所属的某个Deployment的对象
}
}
8. 附加功能:删除流程定义(删除key相同的所有不同版本的流程定义)
// 删除 (使用流程定义的key)
@Test
public void deleteByKey() throws Exception {
// 1,查询指定key的所有版本的流程定义
List<ProcessDefinition> list = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.processDefinitionKey("myProcess")//指定流程定义的key查询
.list();
// 2, 循环删除
for (ProcessDefinition pd : list) {
processEngine.getRepositorySErvice()
.deleteDeployment(pd.getDeploymentId(), true);
}
System.out.println("删除成功!");
}
9. 总结
Deployment 部署对象
1、一次部署的多个文件的信息。对于不需要的流程可以删除和修改。
2、对应的表:
act_re_deployment:部署对象表
act_re_procdef:流程定义表
act_ge_bytearray:资源文件表
act_ge_property:主键生成策略表
ProcessDefinition 流程定义
1、解析.bpmn后得到的流程定义规则的信息,工作流系统就是按照流程定义的规则执行的。