一、前言
最近因为工作需要,需要搭建工作流平台。经过研究后觉得使用activiti6.0作为平台搭建技术。现将学习过程记录下来,此处不记录整合activiti的过程。整合过程另开博客记录。
二、环境准备
笔者环境为:
jdk 1.8
idea 2018.1.1
springboot 2.0.5.RELEASE
三、核心api之RepostoryService
1、创建流程文件TestProcess.bpmn
可以使用图形化界面创建,如图:
创建以后将后缀改为xml,如testProcess.bpmn20.xml
修改后的xml文件内容为:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1538297113127" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="myProcess" isClosed="false" isExecutable="true" name="测试流程" processType="None">
<startEvent id="startevent1" name="Start"/>
<endEvent id="endevent1" name="End"/>
<userTask activiti:assignee="张三" activiti:exclusive="true" id="test" name="用户"/>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="test"/>
<sequenceFlow id="flow2" sourceRef="test" targetRef="endevent1"/>
<bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
//此处省略
</bpmndi:BPMNDiagram>
</definitions>
2、测试代码 如下
/**
*
* 测试RepostoryService
* RepostoryService操作对象:
* 1、部署文件构造器 DeploymentBuilder
* 2、部署文件查询器 DeploymentQuery
* 3、流程定义文件查询对象 ProcessDefinitionQuery
* 4、流程部署文件对象 Deployment
* 5、流程定义文件对象 ProcessDefinition
* 6、流程定义的java格式 BpmnModel
*
*
* @author chaoge
* @since 2018/9/29 17:22
*/
public class RepositoryServiceTest {
private static final LoggerLOGGER = LoggerFactory.getLogger(RepositoryServiceTest.class);
@Rule
public ActivitiRulerule =new ActivitiRule();//默认资源配置文件activiti.cfg.xml
/**
* 测试流程部署
*/
@Test
public void testRepostoryService() {
RepositoryService repositoryService =rule.getRepositoryService();
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();//创建部署流程的builder
Deployment deployment = deploymentBuilder.name("测试部署资源")
.addClasspathResource("processes/TestProcess.bpmn").deploy();
LOGGER.info("deployment = {}", deployment);
//使用repositoryService获取流程部署的query对象,根据这个对象可以获取流程部署信息
DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
Deployment deployment1 = deploymentQuery.deploymentId(deployment.getId()).singleResult();
LOGGER.info("deployment1 = {}", deployment1);
LOGGER.info("deployment = deployment1? {}", deployment1.equals(deployment));//结果居然是false
//输出后两个deployment居然不等,为false debug后发现 deployment下的deploymentTime中fastTime属性不一样
List deployments = deploymentQuery.orderByDeploymenTime().asc().listPage(1, 100);
deployments.forEach(deployment2 -> {
LOGGER.info("deployment1 = {}", deployment2);
//级联删除流程
//repositoryService.deleteDeployment(a.getId(),true);
});
//上面使用了lambda表达式,该方法等同于下面的使用for循环,后面的一样,此处说明方便不会使用lambda的人,会的人直接忽略
// for (Deployment deployment2:deployments){
// LOGGER.info("deployment1 = {}", deployment2);
// }
//使用repositoryService查找流程定义的query对象根据这个对象可以获取流程定义信息
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
List processDefinitions = processDefinitionQuery.listPage(1, 100);
processDefinitions.forEach(
a ->LOGGER.info("processDefinition:{};version:{},key:{};name:{};id:{}"
, a, a.getVersion(), a.getKey(), a.getName(), a.getId())
);
}
/**
* 测试流程定义挂起和激活
*/
@Test
@org.activiti.engine.test.Deployment(resources ="processes/TestProcess.bpmn")//activiti自动部署
public void testSuspend() {
RepositoryService repositoryService =rule.getRepositoryService();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
LOGGER.info("processDefinition.id = {}", processDefinition.getId());
System.out.println("processDefinition.id = " + processDefinition.getId());
//将流程挂起-暂停
//如果已经挂起,则会报错
// org.activiti.engine.ActivitiException:
// Cannot set suspension state 'suspended' for
// ProcessDefinitionEntity[exclusiveGatewayAndTimerBoundaryEventProcess:2:2504]':
// already in state 'suspended'.
repositoryService.suspendProcessDefinitionById(processDefinition.getId());
LOGGER.info("启动流程,但是因为流程已经被挂起,所以此时就会报错 启动的流程id={}", processDefinition.getId());
System.out.println("启动流程,但是因为流程已经被挂起,所以此时就会报错");
//报错信息为org.activiti.engine.ActivitiException:
// Cannot start process instance. Process definition 排他网关和定时边界任务流程
// (id = exclusiveGatewayAndTimerBoundaryEventProcess:2:2504) is suspended
//启动流程
startProcessInstanceById(processDefinition);
//激活流程定义
repositoryService.activateProcessDefinitionById(processDefinition.getId());
startProcessInstanceById(processDefinition);
//删除流程
//repositoryService.deleteDeployment(processDefinition.getId(),true);
}
/**
* 测试用户和用户组
*/
@Test
@org.activiti.engine.test.Deployment(resources ="processes/second_approve.bpmn")//activiti自动部署
public void testCandidateStart() {
RepositoryService repositoryService =rule.getRepositoryService();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
LOGGER.info("processDefinition.id = {}", processDefinition.getId());
System.out.println("processDefinition.id = " + processDefinition.getId());
//添加启动用户,对应流程文件中启动人的Candidate User属性,多个用户以“,”相隔
repositoryService.addCandidateStarterUser(processDefinition.getId(),"use1");
repositoryService.addCandidateStarterGroup(processDefinition.getId(),"groupM");//启动用户组
List identityLinks = repositoryService.getIdentityLinksForProcessDefinition(processDefinition.getId());
identityLinks.forEach(identityLink ->LOGGER.info("identityLink: {}",identityLink));
//删除启动用户及用户组
repositoryService.deleteCandidateStarterUser(processDefinition.getId(),"use1");
repositoryService.deleteCandidateStarterGroup(processDefinition.getId(),"groupM");
}
private void startProcessInstanceById(ProcessDefinition processDefinition) {
try {
System.out.println("开始启动流程");
rule.getRuntimeService().startProcessInstanceById(processDefinition.getId());
System.out.println("流程已启动");
}catch (Exception e) {
System.out.println("流程启动失败");
LOGGER.info("流程启动失败");
LOGGER.info(e.getMessage(), e);
}
}