查询接口中的Xxx即为各类对象的查询方式,如createProcessDefinitionQuery为查询流程定义的方法。查询最后的调用有以下通用方法:javascript
不一样的查询接口须要调用不一样的服务组件,如repositoryService提供流程定义相关的查询;identityService服务组件提供用户、用户组相关的查询;runtimeService提供流程实例相关的查询。java
①常规查询:以下查询为声明了一个流程定义processDefinition来接受查询返回的单个对象,流程定义须要调用repositoryService服务组件中的createProcessDefinition,根据部署的id获取,流程定义的单个实体。sql
ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery(). deploymentId(deployment.getId()).singleResult();
②自定义sql查询:可使用自定义sql去根据数据库字段查询数据:数据库
List<Group> groups=identityService.createNativeGroupQuery().sql("SELECT * FROM ACT_ID_GROUP where NAME=#{name}").parameter("name","group2");
流程定义部署使用DeploymenBuilder对象,该对象提供了如下方法来实现流程部署:dom
如咱们正常部署一个bpmn文件定义的流程定义使用以下代码:异步
DeploymentBuilder builder=repositoryService.createDeployment(); builder.addClasspathResource("test1.bpmn"); builder.deploy();
先使用DeploymenBuilder类来生命了一个builder对象,并经过repositoryService来建立部署,在以后使用builder的addClasspathResource方法将bpmn部署到数据库中,在此过程当中该方法不只回将bpmn文件内容存入数据库,也会根据bpmn生成对应的流程图png文件以通存入数据库。async
流程定义部署完成后,还能够终止或激活流程定义,当终止流程定义时,该流程定义的流程实例不能再被启动。ide
//终止流程定义 repositoryService.suspendProcessDefinitionByKey(ProcessDefinitionKey); //启动流程定义 repositoryService.activateProcessDefinitionByKey(ProcessDefinitionKey);
任务候选人(组):表示该任务能够由某个用户组(如经理)来完成。测试
任务持有人(owner):完成该任务时某我的的职责,那么这我的是此任务的持有人,一个任务只能由一个持有人。ui
任务代理人(assignee):因为本人不能及时处理任务,而委托给他人,这我的就是此任务代理人,一个任务只能由一个代理人。
对任务设置候选人,使用addCandidateUser将用户设置为某我的物的候选人,并将这种绑定关系记录到ACT_RU_IDENTITYLINK表中,代码以下:
String taskId = UUID.randomUUID().toString(); //此处由于只是demo因此直接建立了一个task,正常状况下应该从流程实例中取出task Task task = ts.newTask(taskId); task.setName("测试任务"); ts.saveTask(task); // 建立用户 String userId = UUID.randomUUID().toString(); User user = is.newUser(userId); user.setFirstName("angus"); is.saveUser(user); // 设置任务的候选用户 ts.addCandidateUser(taskId, userId); //设置任务的持有用户 ts.setOwner(taskId, userId); //设置任务的代理人,只能被声明一次代理人,再次声明会报错 ts.claim(taskId, userId);
如何给任务设置参数:
//简单的任务参数保存在ACT_RU_VARIABLE表中 taskSevice.setVariable(task.id,"var1","hello"); //任务参数也能够保存一个对象,可是保存的对应类必须已经实现了serialize可序列话接口 //若是保存对象,数据即序列话后的对象将会额外保存到ACT_GE_BYTEARRAY taskSevice.setVariable(task.id,"person1",p); //取出存入的对象 Person p=taskSevice.getVariable(task.id,"person1",Person.class);
任务参数有着不一样的做用域:
除了使用java代码set参数外,还能够在流程xml文件中保存参数:
<dataObject id="personName" name="personName" itemSubjectRef="xsd:string"> <extensionElements> <activiti:value>Crazyit</activiti:value> </extensionElements> </dataObject>
获取方法以下:
String var = taskService.getVariable(task.getId(), "personName", String.class);
流程实例(ProcessInstance)能够理解为咱们根据流程定义(类)而建立的“对象”。
执行流(Execution)简单理解为工做流图中的一条条线路,而流程实例继承了执行流,所以也被称为著执行流。
ProcessInstance能够直接使用runService的startProcessInstance方法开建立,建立成功后他的数据将会被保存在ACT_RU_EXECUTION表中,须要注意的是尽管流程图如图只有一根线路,数据库中也会出现两条数据,一条为主执行流,一条为子执行流。
不管工做流图是怎么样的,都一定有一个主执行流,而有多少个分支就会有多少个子执行流。
startProcessInstance主要有三类分别是根据id、key和message消息来启动,前两个就是根据流程定义的id、key来启动,最后一个消息是等待一个消息来建立流程实例。
通常流程前进使用trigger方法,使用流程的id传参
Execution exe = runService.createExecutionQuery() .processInstanceId(pi.getId()).onlyChildExecutions() .singleResult(); System.out.println(pi.getId() + ", 当前节点:" + exe.getActivityId()); // 让它往前走 runService.trigger(exe.getId()); exe = runService.createExecutionQuery() .processInstanceId(pi.getId()).onlyChildExecutions() .singleResult(); System.out.println(pi.getId() + ", 当前节点:" + exe.getActivityId());
信号事件:xml形式以下
<signal id="testSignal" name="testSignal"></signal> <process id="myProcess" name="My process" isExecutable="true"> ... <intermediateCatchEvent id="signalintermediatecatchevent1" name="SignalCatchEvent"> <signalEventDefinition signalRef="testSignal"></signalEventDefinition> </intermediateCatchEvent> ... </process>
它须要等待程序发出信号才能继续运行,否则就会在原地等待。
runService.signalEventReceived("testSignal");
消息事件:xml中须要先设定message标签,再在中间抛出事件中,建立消息事件定义,并使用messageRef属性执行message标签。
<message id="testMsg" name="testMsg"></message> <process id="myProcess" name="My process" isExecutable="true"> ... <intermediateCatchEvent id="messageintermediatecatchevent1" name="MessageCatchEvent"> <messageEventDefinition messageRef="testMsg"></messageEventDefinition> </intermediateCatchEvent> ... </process>
相应的程序中也只须要发出相应消息便可工做流继续向前进行
runService.messageEventReceived("testMsg", exe.getId());
区别:从信号和消息的方法参数就能够看出,信号的发送不须要制定特定的对象,而消息是须要制定流程的。简单来讲信号像是广播,只要定义了该信号的人都会收到信号;而消息像私信只有收到消息的目标流程才会继续前行。
异步任务产生的工做:下面的应用会使用到activiti引擎的异步执行,所以须要在activiti.cfg.xml中进行以下配置,开启异步执行,若是不开启此项配置,流程将会卡在ServiceTask不能继续向前运行。
<property name="asyncExecutorActivate" value="true"></property>
以后建立bpmn工做流图,以xml格式打开,更改他的servicetask组件属性
<serviceTask id="servicetask1" name="Service Task" activiti:async="true" activiti:class="org.crazyit.act.c10.MyJavaDelegate"></serviceTask>
activti:class指向的是他要执行的类(类须要实现JavaDelegate接口而且实现execute方法),而async属性则是开启异步执行。
package org.crazyit.act.c10; import org.activiti.engine.delegate.DelegateExecution; import org.activiti.engine.delegate.JavaDelegate; public class MyJavaDelegate implements JavaDelegate { @Override public void execute(DelegateExecution arg0) { System.out.println("这是处理类"); } }
定时器任务:会等待定时结束在继续执行,以下:
<intermediateCatchEvent id="timerintermediatecatchevent1" name="TimerCatchEvent"> <timerEventDefinition> <timeDuration>PT1M</timeDuration> </timerEventDefinition> </intermediateCatchEvent>
被中断的任务:被suspend中断的任务会被写入ACT_RU_SUSPENED表中,同理activate从新激活被中断的任务,任务将会被从表中移除,恢复正常运行。
没法执行的任务:加入一个任务三次抛出异常,就将会被加入ACT_RU_DEADLETTER表中。