安装idea bpmn插件并使用
我的idea版本:2021.2.2
安装插件
安装并重启后,我们在resource文件夹下创建文件夹processes:
右击新建bpmn文件:
创建完成后,会自动生成一个xml文件:
右击,点击查看bpmn流程图:
创建开始事件:
设置name和id:
创建user task
并设置id和name
再创建一个:
创建结束事件:
右击保存成图片,名称为leave.png,并放到resource/processes目录下:
注意xml和png格式:
- png:xxx.png
- xml:xxxx.bpmn20.xml
通过bpmn和png文件部署流程定义
代码:
//部署流程定义
/**
* 部署流程:
* 1. ACT_RE_DEPLOYMENT 流程部署表,每执行一次部署,会插入一条记录
* 2. ACT_RE_PROCDEF 生成流程定义信息
* 其中 ACT_RE_DEPLOYMENT 与 ACT_RE_PROCDEF 表是一对多的关系,
* ACT_RE_PROCDEF 每条记录对应一个流程的定义信息
* 3. ACT_GE_BYTEARRAY 流程资源表,插入资源数据,当前插入两条记录(.bpmn和.png资源)
*/
@Test
public void getProcessEngine() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取部署流程定义的service
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment()
.name("请假申请流程")
.addClasspathResource("processes/leave.bpmn20.xml")
.addClasspathResource("processes/leave.png")
.deploy();
//输出部署结果
System.out.println(deployment.getId());
System.out.println(deployment.getName());
}
运行后,数据库表会增加记录:
zip 流程定义压缩包部署
将 leave.bpmn20.xml和 leave.png 压缩成 leave.zip ,放在类路径下的 processes/leave.zip 。
运行以下代码:
@Test
public void zip() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取部署流程定义的service
RepositoryService repositoryService = processEngine.getRepositoryService();
//读取zip压缩包
InputStream is = ReflectUtil.getResourceAsStream("processes/leave.zip");
ZipInputStream zipInputStream = new ZipInputStream(is);
Deployment deployment = repositoryService.createDeployment()
.name("请假申请流程")
.addZipInputStream(zipInputStream)
.deploy();
//输出部署结果
System.out.println(deployment.getId());
System.out.println(deployment.getName());
}
运行成功:
启动流程实例
流程定义部署后,然后可以通过 activiti 工作流管理业务流程了。例如上一篇部署好了请假流程,可以申请请假了。
针对部署好的流程定义,每次用户发起一个新的请假申请,就对应的启动一个新的请假流程实例;
类似于 java 类与 java 对象(实例)的关系,定义好类后,使用 new 创建一个对象(实例)使用,当然可以 new 多个对象(实例)。
@Test
public void startProcess() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RuntimeService服务实例
RuntimeService runtimeService = processEngine.getRuntimeService();
//启动流程实例(流程定义key)
ProcessInstance instance = runtimeService.startProcessInstanceByKey("leave");
System.out.println("流程定义id:" + instance.getProcessDefinitionId());
System.out.println("流程实例id:" + instance.getId());
}
注意这里的流程定义key要与数据库的这个字段相同:
执行完成后,相对应的数据表会插入记录。
启动流程实例会涉及 activiti 的7张表:
- act_hi_actinst 流程实例执行的节点历史信息
- act_hi_identitylink 流程的参与用户历史信息
- act_hi_procinst 流程实例历史信息
- act_hi_taskinst 流程实例的任务历史信息
- act_ru_execution 流程运行中执行信息
- act_ru_identitylink 流程运行中参与用户信息
查询和完成代办任务
启动流程实例后,每个任务的办理人就可以查询自己当前的待办任务,然后进行办理任务。
@Test
public void taskListByAssignee() {
// 1. 实例化流程引擎实例
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 TaskService
TaskService taskService = processEngine.getTaskService();
// 3. 根据流程唯一标识 key 和 任务办理人 查询任务
List<Task> list = taskService.createTaskQuery()
.processDefinitionKey("leave") // 流程 Key
.taskAssignee("wj1") //办理人名称
.list();
for (Task task : list) {
System.out.println("流程实例id:" + task.getProcessInstanceId());
System.out.println("任务id:" + task.getId());
System.out.println("任务名称:" + task.getName());
System.out.println("任务办理人:" + task.getAssignee());
}
}
完成待办任务
任务办理人查询待办任务,将待办任务进行完成。
/**
* 完成待办任务
*/
@Test
public void completeTask() {
// 1. 实例化流程引擎实例
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 TaskService
TaskService taskService = processEngine.getTaskService();
// 3. 根据流程唯一标识 key 和 任务办理人 查询任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("leave") // 流程 Key
.taskAssignee("wj1")
.singleResult(); // 目前只有一条任务,则可以只获取一条
// 4. 完成任务(任务id)
taskService.complete(task.getId());
}
查询流程实例历史节点信息
查询流程办理历史信息,通过 HistoryService 历史数据对象来获取 HistoricActivityInstanceQuery 历史节点查询对象。
@Test
public void historyInfo(){
// 1. 实例化流程引擎实例
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 HistoryService
HistoryService historyService = processEngine.getHistoryService();
// 3. 获取节点历史记录查询对象 ACT_HI_ACTINST 表
HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery();
// 实例 id
String processInstanceId = "5001";
List<HistoricActivityInstance> list = query.processInstanceId(processInstanceId)
.orderByHistoricActivityInstanceStartTime() // 根据开始时间排序 asc 升序
.asc()
.list();
for (HistoricActivityInstance hi : list) {
System.out.print("流程定义ID: " + hi.getProcessDefinitionId());
System.out.print(",流程实例ID: " + hi.getProcessInstanceId());
System.out.print(",节点ID: " + hi.getActivityId());
System.out.print(",节点名称: " + hi.getActivityName());
System.out.print(",任务办理人:" + hi.getAssignee());
System.out.print(",开始时间:" + hi.getStartTime());
System.out.println("结束时间:" + hi.getEndTime());
}
}