说明
Activiti
核心API
处理一个流程在部署启动以及后面的一系列的操作都是围绕着这几个核心API来完成的。首先这几个API中最重要的是ProcessEngine
流程引擎,其他几个API都是通过流程引擎来创建的。
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
我们可以通过读取源码,看这种方式的创建流程引擎的方式,其实也是通过读取配置文件来创建,只是这里已经帮我们完成了这不操作,不需要我再去Build,直接返回的就是流程引擎对象。ProcessEngines会扫描所有activiti.cfg.xml
和 activiti-context.xml
文件。 对于activiti.cfg.xml文件,流程引擎会使用Activiti的经典方式构建:ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine()
. 对于activiti-context.xml
文件,流程引擎会使用Spring
方法构建:先创建一个Spring的环境, 然后通过环境获得流程引擎。
参考:https://blog.csdn.net/fw19940314/article/details/79538966
创建完成流程引擎,我们就可以来完成一下几个核心API的创建。
API | 描述 |
---|---|
RepositoryService | 管理流程定义 |
RuntimeService | 执行管理,包括启动、推进、删除流程实例等操作 |
TaskService | 任务管理 |
HistoryService | 历史管理(执行完的数据的管理) |
IdentityService | 组织机构管理 |
FormService | 一个可选择的服务 |
ManagerService | 管理服务 |
RepositoryService
createDeployment
部署对象createDeploymentQuery
查询createProcessDefinitionQuery
查询- 挂起暂停流程
- 指定用户及组
测试部署对象和查询:
private static final Logger logger = LoggerFactory.getLogger(RepositoryServiceTest.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
//单次部署
@Test
public void test1(){
RepositoryService repositoryService = activitiRule.getRepositoryService();
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
deploymentBuilder.name("测试部署资源")
.addClasspathResource("diagrams/Second_Approve.bpmn")
.addClasspathResource("diagrams/Simple_Approve.bpmn");
Deployment deployment = deploymentBuilder.deploy();
logger.info("部署信息:{}",deployment);
/** 部署信息:DeploymentEntity[id=7501, name=测试部署资源]*/
//1 查询 deployment
DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
Deployment deployment1 = deploymentQuery
.deploymentId(deployment.getId())
.singleResult();
logger.info("查询到的部署信息:{}",deployment);
/** 部署信息:DeploymentEntity[id=7501, name=测试部署资源]*/
//因为只部署了一次,singleResult获得单个结果
//2 查询流程资源
List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery()
.deploymentId(deployment.getId())
.listPage(0, 100);
//因为有两个部署资源,这里用listPage,不用singleResult
for (ProcessDefinition processDefinition : processDefinitionList) {
logger.info("processDefinition: {}, version:{}, key:{}, id:{}",
processDefinition,processDefinition.getVersion(),processDefinition.getKey(),processDefinition.getId());
//会将两个流程定义文件的信息显示出来。version会在上一次版本+1(入库了)
}
/**processDefinition: ProcessDefinitionEntity[myApply:4:7506], version:4, key:myApply, id:myApply:4:7506
processDefinition: ProcessDefinitionEntity[myProcess:4:7507], version:4, key:myProcess, id:myProcess:4:7507
*/
}
部署对象和查询2:
//多次部署
@Test
public void test2(){
RepositoryService repositoryService = activitiRule.getRepositoryService();
DeploymentBuilder deployment1 = repositoryService.createDeployment();
deployment1.name("测试部署资源1")
.addClasspathResource("diagrams/Second_Approve.bpmn")
.addClasspathResource("diagrams/Simple_Approve.bpmn");
Deployment deploy1 = deployment1.deploy();
DeploymentBuilder deployment2 = repositoryService.createDeployment();
deployment1.name("测试部署资源2")
.addClasspathResource("diagrams/Second_Approve.bpmn")
.addClasspathResource("diagrams/Simple_Approve.bpmn");
Deployment deploy2 = deployment2.deploy();
// 部署了两次,查询结果不能使用singleResult
List<Deployment> deploymentList = repositoryService.createDeploymentQuery()
.orderByDeploymenTime().asc().listPage(0, 100);
logger.info("部署信息list.size:{},信息:{}",deploymentList.size(),deploymentList);
/** 部署信息list.size:15,信息:[DeploymentEntity[id=1, name=??????]...*/
List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery()
.orderByProcessDefinitionKey().asc().listPage(0,100);
logger.info("流程定义信息:{},{}",processDefinitionList.size(),processDefinitionList);
/** 流程定义信息:20,[ProcessDefinitionEntity[myApply:1:6], ProcessDefinitionEntity[myApply:2:2506] */
}
挂起测试:
// 测试挂起/暂停流程
@Test
@org.activiti.engine.test.Deployment(resources = {"diagrams/Second_Approve.bpmn"})
public void test3(){
RepositoryService repositoryService = activitiRule.getRepositoryService();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().list().get(0);
logger.info("processDefinitionId:{}",processDefinition.getId());
// 挂起
repositoryService.suspendProcessDefinitionById(processDefinition.getId());
// 挂起的流程无法启动,除非再次激活
try {
logger.info("开始启动");
activitiRule.getRuntimeService().startProcessInstanceById(processDefinition.getId());
}catch (Exception e){
logger.info("启动失败");
logger.error(e.getMessage(),e);
}
// 再次激活才能启动
repositoryService.activateProcessDefinitionById(processDefinition.getId());
activitiRule.getRuntimeService().startProcessInstanceById(processDefinition.getId());
logger.info("启动成功");
}
测试指定用户组
// 指定用户/组
@Test
@org.activiti.engine.test.Deployment(resources = {"diagrams/Second_Approve.bpmn"})
public void test4(){
RepositoryService repositoryService = activitiRule.getRepositoryService();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().list().get(0);
logger.info("processDefinitionId:{}",processDefinition.getId());
/** processDefinitionId:myApply:10:22506 */
// 设置用户组
repositoryService.addCandidateStarterUser(processDefinition.getId(),"whb");
repositoryService.addCandidateStarterGroup(processDefinition.getId(),"whbG");
// 关系
List<IdentityLink> links = repositoryService.getIdentityLinksForProcessDefinition(processDefinition.getId());
for (IdentityLink link : links) {
logger.info("关系:{}",link);
}
/**
* 关系:IdentityLinkEntity[id=37505, type=candidate, userId=whb, processDefId=myApply:10:22506]
* 关系:IdentityLinkEntity[id=37506, type=candidate, groupId=whbG, processDefId=myApply:10:22506]
*/
// 可以删除指定用户及组
repositoryService.deleteCandidateStarterGroup(processDefinition.getId(),"whbG");
}
RuntimeService
- 启动流程
- 查询:流程实例等
启动流程(3中方式)
private static final Logger logger = LoggerFactory.getLogger(RuntimeServiceTest.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
@Test
@org.activiti.engine.test.Deployment(resources = {"diagrams/Second_Approve.bpmn"})
//1 通过processDefinitionKey启动,用的是最新的版本
public void test1(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String,Object> variables = Maps.newHashMap();
variables.put("key1","value1");
//通过流程key启动
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myApply", variables);//myProcess、myApply
//processDefinitionKey是流程图bpmn文件中的主属性key
logger.info("processInstance信息:{}",processInstance);//processInstance信息:ProcessInstance[42505]
}
//2 通过processDefinitionId启动
@Test
@org.activiti.engine.test.Deployment(resources = {"diagrams/Second_Approve.bpmn"})
public void test2(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessDefinition processDefinition = activitiRule.getRepositoryService().createProcessDefinitionQuery().latestVersion().list().get(0);
Map<String,Object> variables = Maps.newHashMap();
variables.put("key1","value1");
//通过流程id启动
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), variables);//myProcess、myApply
logger.info("processInstance信息:{}",processInstance);//processInstance信息:ProcessInstance[50005]
}
//3 通过instanceBuilder启动
@Test
@org.activiti.engine.test.Deployment(resources = {"diagrams/Second_Approve.bpmn"})
public void test3(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String,Object> variables = new HashMap<>();
variables.put("key1","value1");
//通过instanceBuilder启动
ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
ProcessInstance processInstance = processInstanceBuilder.businessKey("businessKey001")
.processDefinitionKey("myProcess")
.addVariable("testVariable", variables)
.start();
logger.info("processInstance信息:{}",processInstance);//processInstance信息:ProcessInstance[2505]
}
变量:
//测试variables
@Test
public void testVariables() {
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessDefinition processDefinition = activitiRule.getRepositoryService().createProcessDefinitionQuery().latestVersion().list().get(0);
Map<String, Object> variables = Maps.newHashMap();
variables.put("key1", "value1");
variables.put("key2", "value2");
//通过流程id启动
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), variables);//myProcess、myApply
logger.info("processInstance信息:{}", processInstance);
Map<String, Object> variables1 = runtimeService.getVariables(processInstance.getId());
logger.info("variables: {}", variables1); //variables: {key1=value1, key2=value2}
//对变量修改
runtimeService.setVariable(processInstance.getId(), "key1", "newV1");
runtimeService.setVariable(processInstance.getId(), "key3", "value3");
Map<String, Object> variables2 = runtimeService.getVariables(processInstance.getId());
logger.info("variables: {}", variables2); //variables: {key1=newV1, key2=value2, key3=value3}
}
流程实例查询:
//4 查询 流程实例查询
@Test
@org.activiti.engine.test.Deployment(resources = {"diagrams/Second_Approve.bpmn"})
public void testProcessInstance(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessDefinition processDefinition = activitiRule.getRepositoryService().createProcessDefinitionQuery().latestVersion().list().get(0);
Map<String,Object> variables = Maps.newHashMap();
//通过流程id启动
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), variables);//myProcess、myApply
logger.info("processInstance信息:{}",processInstance);//processInstance信息:ProcessInstance[50005]
//查询
ProcessInstance processInstance1 = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstance.getId())
.singleResult();
logger.info("查询到processInstance信息:{}",processInstance1);//查询到processInstance信息:ProcessInstance[15005]
}
流程执行对象查询:
//5 查询 流程执行对象查询
@Test
@org.activiti.engine.test.Deployment(resources = {"diagrams/Second_Approve.bpmn"})
public void testExecution(){
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessDefinition processDefinition = activitiRule.getRepositoryService().createProcessDefinitionQuery().latestVersion().list().get(0);
//通过流程id启动
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());//myProcess、myApply
logger.info("processInstance信息:{}",processInstance);//processInstance信息:ProcessInstance[50005]
//查询
List<Execution> executionList = runtimeService.createExecutionQuery()
.listPage(0, 100);
for (Execution execution : executionList) {
logger.info("查询到的流程执行对象:{}",execution); //查询到的流程执行对象:ProcessInstance[10001]
}
}



将 userTask
换成ReceiveTask
关于
用户任务
和等待任务
的区别:
https://blog.csdn.net/zjx86320/article/details/50385444
https://blog.csdn.net/jiankunking/article/details/52502993
创建如上图所示的流程触发:
Process_Trigger.bpmn
:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="myTrigger" name="我的触发" isExecutable="true">
<startEvent id="startEvent" name="触发"></startEvent>
<sequenceFlow id="flow1" sourceRef="startEvent" targetRef="someTask"></sequenceFlow>
<receiveTask id="someTask" name="ReceiveTask"></receiveTask>
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end"></sequenceFlow>
<endEvent id="end" name="End"></endEvent>
</process>
</definitions>
//流程引擎对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 触发 ReceiveTask
@Test
public void testTrigger(){
//1.部署流程定义
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("diagrams/Process_Trigger.bpmn")
.deploy();
logger.info("deployment信息id:{}",deployment.getId());//deployment信息id:42501
//2.启动流程实例
ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey("myTrigger");
logger.info("流程实例ID:{}", processInstance.getId());//流程实例ID:42504
logger.info("流程定义ID:{}",processInstance.getProcessDefinitionId());//流程定义ID:myTrigger:5:42503
//3.查询执行对象表,使用流程实例ID和当前活动的名称(someTask)
Execution execution = processEngine.getRuntimeService()
.createExecutionQuery()
.processInstanceId(processInstance.getId())
.activityId("someTask").singleResult();
logger.info("execution :{}",execution);//execution :ProcessInstance[42504]
//触发 有的版本是trigger、新版本换成了signal
processEngine.getRuntimeService().signal(execution.getId());
//发送信号后,此时再判断执行对象发现是null,流程结束了
Execution execution1 = processEngine.getRuntimeService().createExecutionQuery()
.processInstanceId(processInstance.getId()).activityId("someTask").singleResult();
logger.info("execution1 :{}",execution1);//execution1 :null
}
其他启动方式:Message、Signal等,参考:
https://www.cnblogs.com/dengjiahai/p/7191865.html
https://blog.csdn.net/luckyzhoustar/article/details/48650563