上一篇文章讲解了工作流框架Activiti相关的基础知识,了解了Activiti的基本架构及其使用步骤。这次通过一个简单的入门程序来演示Activiti的简单使用。
1、流程定义
1.1 Palette(画板)
在eclipse或idea(本次使用)中安装activiti-designer插件即可使用,画板中包括以下结点:
Connection—连接
Event---事件
Task---任务
Gateway---网关
Container—容器
Boundary event—边界事件
Intermediate event- -中间事件
流程图设计完毕保存生成.bpmn文件。
1.2 新建流程
首先选中存放图形的目录(本次我们选择resources下的bpmn目录),点击菜单:New-BpmnFile,如下图所示:
起完名字holiday后(默认扩展名为bpmn),就可以看到进入了流程设计页面,如图所示:
1.3 指定流程定义key
流程定义key即流程定义的标识,在eclipse中通过properties视图查看流程的key,在IDEA中,点击左边的BPMN editor来定义。
建议:相同的业务流程,流程定义的key名字定义不一样,比如,如果需要创建新的业务流程,请假流程则使用新的key。
1.4 指定任务负责人
1.5 生成流程定义对应的png图片
我们发现,流程图画完之后,没有像Eclipse里面一样,自动给我们生成对应png图片,IDEA中,要生成图片,需要执行如下操作:
1、重命名刚才创建的holiday.bpmn文件,把后缀改成xml
2、然后右键单击文件,如下:
会出现如下所示:
点击按钮,把文件保存到和holiday.xml文件相同的目录下面,命名为holiday.png,我们就会发现bpmn目录下会出现文件holiday.png文件。
1.6 解决holiday.png的中文乱码问题
我们可以看到图片中的中文是乱码的,执行下面的操作即可解决:
找到IDEA的安装目录,找到bin目录,比如我的路径:D:\IDEA\JetBrains\IntelliJIDEA2017.3.4\bin
找到这两个文件:
具体要修改哪个文件,由你安装的IDEA的版本来决定,如果你安装了64位版本的IDEA,那么就修改idea64.exe.vmoptions。
具体修改的方法是在文件后面追加一条命令: -Dfile.encoding=UTF-8
一定注意,不要有空格,否则重启IDEA时会打不开,然后 重启IDEA,把原来的png图片删掉,再重新生成,即可解决乱码问题
解决问题后,把xml文件重新改成bpmn格式,和png图片一起压缩成zip包进行部署
2、部署流程定义
部署流程定义就是要将上边绘制的图形即流程定义(.bpmn)部署在工作流程引擎activiti中,方法如下:
使用ProcessEngine创建RepositoryService,代码如下:
package com.zdw.activiti;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import java.io.InputStream;
import java.util.zip.ZipInputStream;
/**
* 流程定义部署
* activiti表有哪些?
* act_re_deployment 部署信息
act_re_procdef 流程定义的一些信息
act_ge_bytearray 流程定义的bpmn文件及png文件
*/
public class ActivitiDeployment {
//流程定义部署 流程制作出来后要上传到服务器 zip文件更便于上传(bpmn和png单独上传也可以,下面也会演示)
public static void main(String[] args) {
//创建ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//得到RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//---------方式一 部署开始:
//转化出ZipInputStream流对象
//InputStream inputStream = ActivitiDeployment.class.getClassLoader().getResourceAsStream("bpmn/holiday.zip");
//将 inputstream流转化为ZipInputStream流
//ZipInputStream zipInputStream = new ZipInputStream(inputStream);
//部署
//Deployment deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).name("请假流程").deploy();
//--------方式一 部署结束:
//--------方式二部署开始
Deployment deployment = repositoryService.createDeployment().addClasspathResource("bpmn/holiday.bpmn")
.addClasspathResource("bpmn/holiday.png").name("请假流程").deploy();
//--------方式二部署结束
//4.输出部署的一些信息
System.out.println(deployment.getName());
System.out.println(deployment.getId());
}
}
执行此操作后activiti会将上边代码中指定的bpm文件和图片文件保存在activiti数据库。可以通过下面的语句查询:
SELECT * FROM ACT_RE_PROCDEF;
SELECT * FROM ACT_RE_DEPLOYMENT;
SELECT * FROM act_ge_bytearray;
3、启动一个流程实例
流程定义部署在activiti后就可以通过工作流管理业务流程了,也就是说上边部署的请假申请流程可以使用了。
针对该流程,启动一个流程表示发起一个新的请假申请单,这就相当于java类与java对象的关系,类定义好后需要new创建一个对象使用,当然可以new多个对象。对于请假申请流程,张三发起一个请假申请单需要启动一个流程实例,请假申请单发起一个请假单也需要启动一个流程实例。
代码如下:
package com.zdw.activiti;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
/**
* Create By zdw on 2019/8/2
* 启动流程实例:
* 前提是先已经完成流程定义的部署工作
*
* 背后影响的表:
* act_hi_actinst 已完成的活动信息
act_hi_identitylink 参与者信息
act_hi_procinst 流程实例
act_hi_taskinst 任务实例
act_ru_execution 执行表
act_ru_identitylink 参与者信息
act_ru_task 任务
*/
public class ActivitiStartInstance {
public static void main(String[] args) {
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.根据流程定义key启动流程,得到流程实例ProcessInstance
ProcessInstance instance = runtimeService.startProcessInstanceByKey("myholiday");
//4.输出实例的相关信息
System.out.println("流程部署ID"+instance.getDeploymentId());
System.out.println("流程定义ID"+instance.getProcessDefinitionId());
System.out.println("流程实例ID"+instance.getId());
System.out.println("活动ID"+instance.getActivityId());
}
}
4、任务查询
流程启动后,各各任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。
package com.zdw.activiti;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import java.util.List;
/**
* Create By zdw on 2019/8/2
* 查询当前用户的任务列表
*/
public class ActivitiTaskQuery {
public static void main(String[] args) {
//zhangsan任务列表的查询
queryZsTask();
}
//zhangsan任务列表的查询
private static void queryZsTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//得到TaskService
TaskService taskService = processEngine.getTaskService();
//根据流程定义key和任务负责人来查询该负责人的任务列表
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey("myholiday").taskAssignee("zhangsan").list();
//4.任务列表的展示
for(Task task :taskList){
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("任务ID:"+task.getId());
System.out.println("任务负责人:"+task.getAssignee());
System.out.println("任务名称:"+task.getName());
}
}
}
5、任务处理
任务负责人查询待办任务,选择任务进行处理,完成任务。
package com.zdw.activiti;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.TaskService;
/**
* 处理当前用户的任务
* 背后操作的表:
* act_hi_actinst
act_hi_identitylink
act_hi_taskinst
act_ru_identitylink
act_ru_task
*/
public class ActivitiCompleteTask {
public static void main(String[] args) {
//张三完成自己的任务
completeTaskForZs();
}
//张三完成自己的任务
private static void completeTaskForZs() {
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到TaskService对象
TaskService taskService = processEngine.getTaskService();
//3.处理任务,结合当前用户任务列表的查询操作的话,任务ID:2505
taskService.complete("2505");
}
}
我们可以根据张三这种完成任务的情况,可以去完成lisi和wangwu,zhaoliu等的任务。