Activiti学习笔记第五篇:管理流程定义

1.设计流程定义文档

1.1流程图

Activiti学习笔记第五篇:管理流程定义

1.2 bpmn文件

.  BPMN 2.0根节点是definitions节点。 这个元素中,可以定义多个流程定义(不过我们建议每个文件只包含一个流程定义, 可以简化开发过程中的维护难度)。 一个空的流程定义看起来像下面这样。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的声明。 targetNamespace可以是任意值,它用来对流程实例进行分类。
Activiti学习笔记第五篇:管理流程定义
说明:流程定义文档有两部分组成:

  1. bpmn文件
      流程规则文件。在部署后,每次系统启动时都会被解析,把内容封装成流程定义放入项目缓存中。Activiti框架结合这个xml文件自动管理流程,流程的执行就是按照bpmn文件定义的规则执行的,bpmn文件是给计算机执行用的
  2. 展示流程图的图片
      在系统里需要展示流程的进展图片,图片是给用户看的

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();
}

说明:

  1. 先获取流程引擎对象:在创建时会自动加载classpath下的activiti.cfg.xml
// 创建流程引擎对象
private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
  1. 首先获得默认的流程引擎,通过流程引擎获取了一个RepositoryService对象(仓库对象)
  2. 由仓库的服务对象产生一个部署对象配置对象,用来封装部署操作的相关配置。
  3. 这是一个链式编程,在部署配置对象中设置显示名,上传流程定义规则文件
  4. 向数据库表中存放流程定义的规则信息。
  5. 这一步在数据库中将操作三张表:
    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());
}

Activiti学习笔记第五篇:管理流程定义压缩成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("*******************");
	}
}

结果:
Activiti学习笔记第五篇:管理流程定义
再部署一次运行结果为:
Activiti学习笔记第五篇:管理流程定义
可以看到流程定义的key值相同的情况下,版本是从1开始逐次升级的
流程定义的Id是【key:版本:生成ID】
   说明:

  1. 流程定义和部署对象相关的Service都是RepositoryService。
  2. 创建流程定义查询对象,可以在ProcessDefinitionQuery上设置查询的相关参数
  3. 调用ProcessDefinitionQuery对象的list方法,执行查询,获得符合条件的流程定义列表
  4. 由运行结果可以看出:
    Key和Name的值为:bpmn文件process节点的id和name的属性值
    <process id="LeaveFlow" name="请假流程" isExecutable="true">
  5. key属性被用来区别不同的流程定义。
  6. 带有特定key的流程定义第一次部署时,version为1。之后每次部署都会在当前最高版本号上加1
  7. Id的值的生成规则为:{processDefinitionKey}:{processDefinitionVersion}:{generated-id}, 这里的generated-id是一个自动生成的唯一的数字
  8. 重复部署一次,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);
}

说明:

  1. 因为删除的是流程定义,而流程定义的部署是属于仓库服务的,所以应该先得到RepositoryService
  2. 如果该流程定义下没有正在运行的流程,则可以用普通删除。如果是有关联的信息,用级联删除。项目开发中使用级联删除的情况比较多,删除操作一般只开放给超级管理员使用。

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);
	}
}

说明:

  1. deploymentId为流程部署ID
  2. resourceName为act_ge_bytearray表中NAME_列的值
  3. 使用repositoryService的getDeploymentResourceNames方法可以获取指定部署下得所有文件的名称
  4. 使用repositoryService的getResourceAsStream方法传入部署ID和资源图片名称可以获取部署下指定名称文件的输入流
  5. 最后的有关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后得到的流程定义规则的信息,工作流系统就是按照流程定义的规则执行的。