记下笔记,方便日后查询,如有错误,请指出,共同进步。
什么是流程定义 ?(重要)
流程定义是按照bpmn2.0标准定义业务流程,将流程定义的文件(.bpmn和.png(不是必须的))部署到activiti中,activiti就可以管理该业务流程。
什么是流程实例 ?(重要)
参与者(可以用户,也可以程序)按照流程定义发起一个流程,这个流程就是一个流程实例 。流程定义的内容就是一个静态文件(.bpmn),流程实例的内容是该 流程的执行过程(动态)。
转载自:https://www.cnblogs.com/kimi9py/p/5697211.html
--------------------------------------------------------------------------------------------------------------------------
任务是任务~当挂起一个流程实例后,后续的任务无法继续进行,无法对其任务进行任何操作(加签、转办等)只有运行中的流程可以挂起或激活
定义是定义~当挂起XXXXXX定以后,无法再次申请该XXX定义的流程
挂起流程定义也可以级联挂起实例,实例被挂起,任务自然也就挂起了(一般默认是不级联的吧)
流程变量:(在文章下面还有介绍)
流程变量分全局和局部两种:
1 全局变量测试
1.1 什么时候设置流程变量?
采购流程中,在提交采购单时设置流程变量,因为提交采购单后采购单信息不再修改了。
使用完成提交采购单任务时设置流程变量。
// 完成任务时设置流程变量,使用pojo
OrderCustom orderCustom = new OrderCustom();
orderCustom.setPrice(10000f);
Map<String, Object> varaibles = new HashMap<String, Object>();
varaibles.put("order", orderCustom);
taskService.complete(taskId, varaibles);
2 设置局部变量
2.1 在任务完成设置局部变量
在任务完成时设置局部变量,任务完成后,后续结点无法使用局部变量。
// 完成任务时设置流程变量,使用pojo
OrderCustom orderCustom = new OrderCustom();
orderCustom.setPrice(10000f);
Map<String, Object> varaibles = new HashMap<String, Object>();
varaibles.put("order", orderCustom);
//设置局部变量
taskService.setVariablesLocal(taskId, varaibles);
//完成任务
taskService.complete(taskId);
当局部变量消失后,再使用该变量会报错。
转载自:http://www.cnblogs.com/skilltalent-huan/articles/5078454.html
转载自:https://www.cnblogs.com/kimi9py/p/5697211.html
--------------------------------------------------------------------------------------------------------------------------
部署流程定义:
/**部署流程定义*/
//部署方法一:classpath单流程部署方式
/*@Test
public void deploymentProcessDefinition(){
Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
.createDeployment()//创建一个部署对象
.name("请假流程")//添加部署的名称
.addClasspathResource("diagrams/Leave.bpmn")//从classpath的资源中加载,一次只能加载一个文件
.addClasspathResource("diagrams/Leave.png")//从classpath的资源中加载,一次只能加载一个文件
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//1
System.out.println("部署名称:"+deployment.getName());//helloworld入门程序
}*/
//部署方法二:zip多流程部署方式
@Test
public void deployementProcessDefinitionByzip(){
//从classpath路径下读取资源文件
InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/packageZIP/diagrams.zip");
ZipInputStream zipInputStream = new ZipInputStream(in);
Deployment deployment = processEngine.getRepositoryService()//获取流程定义和部署对象相关的Service
.createDeployment()//创建部署对象
.name("请假流程")
.addZipInputStream(zipInputStream)//使用zip方式部署,将helloworld.bpmn和helloworld.png压缩成zip格式的文件
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//1
System.out.println("部署时间:"+deployment.getDeploymentTime());
System.out.println("部署名称:"+deployment.getName());
}
启动流程实例:操作的表有(都是insert):act_ru_execution(流程实例表)、act_ru_task(任务表)
//流程定义的key
String processDefinitionKey = "LeaveProcess";
ProcessInstance pi = processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的Service
.startProcessInstanceByKey(processDefinitionKey);//使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
System.out.println("流程实例ID:"+pi.getId());//流程实例ID 101
System.out.println("流程定义ID:"+pi.getProcessDefinitionId());//流程定义ID helloworld:1:4
查询个人任务:act_ru_task(任务表)
String assignee = "张三";
List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
.createTaskQuery()//创建任务查询对象
.taskAssignee(assignee)//指定个人任务查询,指定办理人
.list();
if(list!=null && list.size()>0){
for(Task task:list){
taskId=task.getId();
System.out.println("任务ID:"+taskId);
System.out.println("任务名称:"+task.getName());
System.out.println("任务的创建时间:"+task.getCreateTime());
System.out.println("任务的办理人:"+task.getAssignee());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("执行对象ID:"+task.getExecutionId());
System.out.println("流程定义ID:"+task.getProcessDefinitionId());
System.out.println("########################################################");
}
}
完成任务:操作的数据表:
act_ru_execution,操作是update 更新字段act_id(存放流程节点的id)
act_ru_task,操作是先delete 然后 insert
Map<String, Object> variables = new <String,Object> HashMap(); //流程变量 用于控制流程走向
boolean bl=false;
String id="77504"; // 主管 manager 人事 approval 调整 SubAndAbrogate
variables.put("SubAndAbrogate", bl);
processEngine.getTaskService()//与正在执行的任务管理相关的Service
.complete(id,variables);//第一个入参是任务id 第二个入参是流程变量(局部)
查询流程状态:
ProcessInstance pi=processEngine.getRuntimeService() // 获取运行时Service
.createProcessInstanceQuery() // 创建流程实例查询
.processInstanceId("2501") // 用流程实例id查询
.singleResult();
if(pi!=null){
System.out.println("流程正在执行!");
}else{
System.out.println("流程已经执行结束!");
}
查询流程定义:
/*
* 查询流程定义 查询的表就是 act_re_procdef
* */
@Test
public void queryProcessEngine(){
ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
query.processDefinitionKey("LeaveProcess");//根据key过滤
query.orderByProcessDefinitionVersion().asc();
List<ProcessDefinition> list = query.listPage(10, 20);
for (ProcessDefinition processDefinition : list) {
System.out.println(processDefinition.getId());
}
设置流程变量:
流程变量以键值对存在,存放在表 act_ru_variable中,当流程实例结束时,对应的流程变量数据会被框架删除
设置流程变量的方式:
1.启动流程实例时设置:
/**
* 启动流程实例时设置流程变量
*/
@Test
public void test2() {
String processDefinitionKey = "bxlc";// 流程定义key
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("key1", "value1");
variables.put("loginUser", "小王");
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceByKey(processDefinitionKey, variables);
System.out.println(pi.getId());
}
2.办理任务时设置:
/**
* 办理任务时设置流程变量
*/
@Test
public void test3() {
String taskId = "206";//任务id
Map<String, Object> variables = new HashMap<>();
variables.put("qjyy", "不想上班");
variables.put("qjts", 365);
processEngine.getTaskService().complete(taskId, variables);
}
查询流程定义:
1 排他网关:
排他网关只会有一条为true的顺序流流出,如果有多条顺序流结果为true,那么选择第一条,如果没有结果为true的顺序流则会抛出一个异常。
2 并行网关:
并行网关它允许将流程 分成多条分支,也可以把多条分支 汇聚到一起。
分支: 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
汇聚: 所有分支在这里汇聚,先到的分支会等待还在执行的分支,只有所有分支全部汇聚完成,才会进入下一个任务。
注意并行网关不需要是“平衡的”(比如, 对应并行网关的进入和外出节点数目相等)。 并行网关只是等待所有进入顺序流,并为每个外出顺序流创建并发分支, 不会受到其他流程节点的影响。 所以下面的流程在BPMN 2.0中是合法的:
3 包含网关:
包含网关可以看做是排他网关和并行网关的结合体。 和排他网关一样,你可以在外出顺序流上定义条件,包含网关会解析它们。 但是主要的区别是包含网关可以选择多于一条顺序流,这和并行网关一样。
包含网关的功能是基于进入和外出顺序流的:
分支: 所有外出顺序流的条件都会被解析,结果为true的顺序流会以并行方式继续执行, 会为每个顺序流创建一个分支。
汇聚: 所有并行分支到达包含网关,会进入等待章台, 直到每个包含流程token的进入顺序流的分支都到达。 这是与并行网关的最大不同。换句话说,包含网关只会等待被选中执行了的进入顺序流。 在汇聚之后,流程会穿过包含网关继续执行。
注意,如果同一个包含节点拥有多个进入和外出顺序流, 它就会同时含有分支和汇聚功能。 这时,网关会先汇聚所有拥有流程token的进入顺序流, 再根据条件判断结果为true的外出顺序流,为它们生成多条并行分支。
在上面的例子中,流程开始之后,如果流程变量为paymentReceived == false和shipOrder == true, 就会创建两个任务。如果,只有一个流程变量为true,就会只创建一个任务。 如果没有条件为true,就会抛出一个异常。 如果想避免异常,可以定义一个默认顺序流。