一、activiti配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- spring模式加载的class不同 -->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db_activiti" />
<!-- 数据库配置也可以直接用数据源dataSource注入 -->
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="root" />
<!-- false:关闭;true:当表不存在时自动创建;create-drop/drop-create -->
<property name="databaseSchemaUpdate" value="true" />
<!-- 监控流程作业,默认false -->
<property name="jobExecutorActivate" value="false" />
<!--
none: 跳过所有的历史数据。性能最优,但是没有历史数据。
activity: 保存所有的流程实例和活动信息。只保留最后信息,没有明细信息。
audit: 默认级别。保存所有的流程实例,任务、活动、表单属性等信息。
full: 最高级别,最完整的的历史信息。除了audit中的信息外,还包含详细信息。
-->
<property name="history" value="audit" />
<!-- 打开异步处理Service任务 -->
<property name="asyncExecutorActivate" value="true"></property>
<!-- 发布流程不生成流程图 -->
<property name="createDiagramOnDeploy" value="false" />
<!-- 字体 -->
<property name="activityFontName" value="宋体" />
<property name="labelFontName" value="宋体" />
<!-- 不保存流程图片 -->
<property name="createDiagramOnDeploy" value="false" />
<property name="DbIdentityUsed" value="true" />
<property name="DbHistoryUsed" value="true" />
<property name="databaseTablePrefix" value="T_" />
<property name="databaseType" value="mysql" />
</bean>
</beans>
二、数据库表
activiti6.0新增:
- ACT_RU_TIMER_JOB 存放定时任务
- ACT_RU_SUSPENDED_JOB 存放暂停任务
- ACT_RU_DEADLETTER_JOB 无法执行的任务
- ACT_EVT_LOG 异步日志表
- ACT_PROCDEF_INFO 流程定义扩展表
三、service接口
RepositoryService
流程仓库Service,用于管理流程仓库,如部署、删除、读取流程资源。
IdentifyService
身份Service,管理和查询用户、组之间的关系。
RuntimeService
运行时Service,管理所有正在运行状态的流程实例、任务等。
TaskService
任务Service,用于管理、查询任务,如签收、办理、指派等。
FormService
表单Service,用于读取和流程、任务相关的表单数据。
HistoryService
历史Service,可以查询所有历史数据。
ManagementService
引擎管理Service,和具体业务无关,主要是可以查询引擎配置、数据库、作业等。
7个service都是通过ProcessEngine对象来获取的
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
四、activiti流程设计器使用(BPMN2.0规范)
事件
1、事件的分类与定义
定时器事件定义
可以用在开始事件、中间事件、边界事件。可选指定时间触发、循环触发。支持cron表达式
错误事件定义
可以用在开始事件、结束事件、边界事件。捕获/抛出错误。
信号事件定义
通过一个信号控制多个流程实例,可以用在边界事件、中间事件。
消息事件定义
一个消息控制一个流程实例
取消事件定义
用在事务子流程模型中,有取消边界事件和取消结束事件
补偿事件定义
补偿事件
其他事件
2、开始事件
- 无指定开始事件
定时器开始事件
必须在配置文件打开异步处理Service任务,可以设置定时器触发方式
消息开始事件
通过消息名称启动流程:
ProcessInstance pi = runService.startProcessInstanceByMessage(“msgName”);
流程配置文件添加<message id="msgA" name="msgName"></message>
- 错误开始事件
流程中抛出异常,在事件子流程开始错误事件中捕获异常
流程配置文件添加<error id="countError" errorCode="abc"></error>
处理类抛出throw new org.activiti.engine.delegate.BpmnError("abc");
3、结束事件
无指定结束事件
错误结束事件
流程以错误事件结束,然后事务子流程中就会捕获,从而执行子流程。或者触发边界错误捕获流程。
取消结束事件
在事务子流程中,触发取消结束事件后,就会触发所有补偿边界事件,然后先执行补偿边界事件,再判断整个事务子流程中是否有边界事件,有就执行事务子流程中的。
1
2
3
4<endEvent id="cancelendevent1" name="CancelEnd">
<cancelEventDefinition></cancelEventDefinition>
</endEvent>
>终止结束事件
当一个流程实例中,有多个任务都可以执行(并行网关),有一条执行到了终止结束事件,那么整个流程实例都终止了。
4、边界事件
定时器边界事件
当触发定时器时,执行定时器指定的任务
错误边界事件
捕获异常:
throw new org.activiti.engine.delegate.BpmnError("abc");
信号边界事件
,当执行到某个节点的时候触发信号或者消息时,执行另一个任务。申请–>审批–>审批不通过触发事件–>回到申请
取消边界事件
当事务子流程中,取消结束事件被触发后,补偿边界事件触发,然后子流程取消边界事件也会触发
补偿边界事件
1
2
3
4<boundaryEvent id="boundarycompensation1" name="Compensate" attachedToRef="usertask1" cancelActivity="true">
<compensateEventDefinition></compensateEventDefinition>
</boundaryEvent>
>
5、中间事件
- 定时器中间事件(捕获)
必须等待定时器触发后才能执行后面的节点任务(下个节点延迟拿到执行)
1
2
3
4
5
6<intermediateCatchEvent id="timerintermediatecatchevent1"
name="TimerCatchEvent">
<timerEventDefinition>
<timeDuration>PT5S</timeDuration>
</timerEventDefinition>
</intermediateCatchEvent>
>
信号中间事件(捕获和抛出)
比如并行网关里,多条执行任务都是捕获信号中间事件,然后其中一条任务执行完成后,抛出信号中间事件,其他有捕获信号中间时间的执行任务才能往下走。(中间信号事件是自动触发的)
1
2
3
4
5
6
7
8
9
10
11<signal id="finishPay" name="finishPay"></signal>
<!-- 捕获 -->
<intermediateThrowEvent id="signalintermediatethrowevent1" name="SignalThrowEvent">
<signalEventDefinition signalRef="finishPay"></signalEventDefinition>
</intermediateThrowEvent>
<!-- 抛出 -->
<intermediateCatchEvent id="signalintermediatecatchevent2"
name="SignalCatchEvent">
<signalEventDefinition signalRef="finishPay"></signalEventDefinition>
</intermediateCatchEvent>
>消息中间事件(捕获)
1
2
3
4 Execution run = runService.createExecutionQuery().messageEventSubscriptionName("message").singleResult();
System.out.println(run.getId());
runService.messageEventReceived("message", run.getId());
>
- 信号中间事件
1
2
3
4
5
6
7
8
9 // 启动流程
ProcessInstance pi = runService.startProcessInstanceById(pd.getId());
// 查当前的子执行流(只有一个)
Execution exe = runService.createExecutionQuery()
.processInstanceId(pi.getId()).onlyChildExecutions()
.singleResult();
System.out.println(pi.getId() + ", 当前节点:" + exe.getActivityId());
runService.signalEventReceived("testSignal");
>
- 补偿中间事件
6、补偿事件
补偿边界事件
- 事务子流程有取消结束事件就会执行子流程中补偿边界事件
- 触发补偿中间事件==>触发边界补偿事件
补偿中间事件
触发补偿中间事件就会触发所有之前任务的边界补偿事件
任务
1、用户任务
分配任务的候选人
- 方式1:使用taskService的addCandidateGroup和addCandidateUser方法
- 方式2:使用XML配置
id 1
2
3
4
5
6
7<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>user(angus), group(management), boss
</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
分配任务代理人
一个任务可以分配多个候选人,但是只能有一个代理人- 方式1:使用task对象的setAssignee方法设置代理人
- 方式2:使用XML配置
id 1
2
3
4
5
6<humanPerformer>
<resourceAssignmentExpression>
<formalExpression>user</formalExpression>
</resourceAssignmentExpression>
</humanPerformer>
> </userTask>
权限分配扩展
1
2
3
4<userTask id="usertask1" name="Task A" activiti:assignee="user1"
activiti:candidateUsers="angus,angus1" activiti:candidateGroups="boss,management">
</userTask>
>
当设置代理人的时候,该任务只属于该代理人
使用任务监听器进行权限分配
见监听器
使用JUEL分配权限
1
2
3
4<userTask id="usertask1" name="My Task" activiti:candidateUsers="${authService.getCandidateUsers()}"
activiti:candidateGroups="${authService.getCandidateGroups()}" activiti:assignee="${authService.getAssignee()}"
></userTask>
>
启动流程:
1
2
3
4 Map<String, Object> vars = new HashMap<String, Object>();
vars.put("authService", new AuthService());
ProcessInstance pi = runService.startProcessInstanceById(pd.getId(), vars);
>AuthService类中方法返回
List<String>
获取String
类型即可
2、服务任务
Java Service Task
- activiti:class:必须是该两个接口的实现类JavaDelegate、ActivityBehavior
必须写死类路径
activiti:delegateExpression
activiti:delegateExpression="${myDelegate}"
1
2
3
4
5
6
7//MyDelegate实现JavaDelegate和Serializable
MyDelegate de = new MyDelegate();
Map<String ,Object> vars = new HashMap<String, Object>();
vars.put("myDelegate", de);
// 启动流程
ProcessInstance pi = runService.startProcessInstanceById(pd.getId(), vars);
>activiti:expression
activiti:expression="${myBean.print(execution)}"
activiti:expression="${execution.setVariable('myName', myBean.name)}"
1
2
3
4
5
6Map<String ,Object> vars = new HashMap<String, Object>();
//print方法传入Execution exe,可以获取当前的任务
vars.put("myBean", new MyBean());//实现Serializable接口,并且有name成员变量,getName方法
// 启动流程
ProcessInstance pi = runService.startProcessInstanceById(pd.getId(), vars);
>
- activiti:class:必须是该两个接口的实现类JavaDelegate、ActivityBehavior
JavaDelegate 会自动执行,ActivityBehavior 会等待
- Shell Task
1
2
3
4
5
6
7
8
9
10<serviceTask id="servicetask1" name="Service Task" activiti:type="shell">
<extensionElements>
<activiti:field name="command" stringValue="cmd"/>
<activiti:field name="arg1" stringValue="/c"/>
<activiti:field name="arg2" stringValue="echo"/>
<activiti:field name="arg3" stringValue="%JAVA_HOME%"/>
<activiti:field name="outputVariable" stringValue="javaHome"/>
</extensionElements>
</serviceTask>
>
获取参数值
runService.getVariable(pi.getId(), "javaHome")
- Receive Task
1
2
3
4
5
6
7
8
9
10 // 启动流程
ProcessInstance pi = runService.startProcessInstanceById(pd.getId());
// 查当前的子执行流(只有一个)
Execution exe = runService.createExecutionQuery()
.processInstanceId(pi.getId()).onlyChildExecutions()
.singleResult();
System.out.println(pi.getId() + ", 当前节点:" + exe.getActivityId());
// 让它往前走
runService.trigger(exe.getId());
>
Web Service Task
用不上
3、其他任务与流程监听器
其他任务
手工任务
自己会执行,会记录历史数据
- 接收任务: RuntimeService.trigger(exe.getId())
- 邮件任务
自动发送邮件
- Mule任务
- 业务规则任务
任务监听器
同Service Task有三种配置方式:
- class
- delegateExpression
- expression
监听器触发:
create
流程创建时
assignment
流程任务分配
complete
任务完成
1 | <userTask id="usertask1" name="User Task" activiti:assignee="crazyit"> |
监听器也可以获取流程中设置的参数
监听器实现TaskListener接口1
2
3
4
5
6
7
8
9
10
11
12
13
14public class MyTaskListener implements TaskListener {
private FixedValue userName;
public void setUserName(FixedValue userName) {
this.userName = userName;
}
public void notify(DelegateTask arg0) {
System.out.println("这是自定义任务监听器, " + userName.getExpressionText());
}
}
流程监听器
监听器触发:
start
流程开始
take
流程经过
end
流程完成
1 | <extensionElements> |
监听器实现类是ExecutionListener
流程网关其他
1、子流程
- 嵌入式子流程
子流程与外部任务交互必须经过边界事件
调用式子流程
调用外部流程添加callActivity节点,指定外部流程ID:SubProcess
<callActivity id="callactivity1" name="调用其他的流程" calledElement="SubProcess"></callActivity>
获取外部流程的实例:ProcessInstance piSub = runService.createProcessInstanceQuery(). superProcessInstanceId(pi.getId()).singleResult();
传递参数:1
2
3
4
5<extensionElements>
<activiti:in source="days" target="newDays"/>
<activiti:out source="myDays" target="resultDays"/>
</extensionElements>
>事件子流程
可以由错误、信号、消息、定时器事件触发
- 事务子流程
在事务子流程中出现异常,子流程边界错误事件会捕捉到。事务子流程中出现取消结束流程,会触发之前的流程任务的边界补偿事务,同时触发子流程取消边界事务
- 特别子流程
6.0 新增,在该子流程中,不存在执行顺序,由执行时决定
2、顺序流与网关
条件顺序流1
2
3
4<sequenceFlow id="flow3" sourceRef="exclusivegateway1" targetRef="usertask2">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${days <= 3 || day == 5}]]></conditionExpression>
</sequenceFlow>
如果是条件网关的话,不满足条件会报错。多条满足,会默认走第一个
普通顺序流
一个任务不能出现多条普通顺序流吧
网关
- 单向网关
与条件顺序流一起使用,只能有一个条件通过并行网关
兼容网关
单向网关和并行网关结合体- 事件网关
和中间事务结合使用,多个任务的时候,哪个任务先触发就执行哪条任务- 组合网关
不支持
3、流程活动的特性
多实例流程活动
创建多个任务实例
1
2
3
4
5
6
7<serviceTask id="servicetask1" name="Service Task" activiti:class="org.crazyit.act.c10.ForeachDelegate">
<multiInstanceLoopCharacteristics
isSequential="false">
<loopCardinality>3</loopCardinality>
</multiInstanceLoopCharacteristics>
</serviceTask>
>设置循环数据(6.0版本)
1
2
3
4Map<String, Object> vars = new HashMap<String, Object>();
vars.put("datas1", datas1); //List<String>格式
ProcessInstance pi = runService.startProcessInstanceById(pd.getId(), vars);
>
1
2
3
4
5
6 <serviceTask id="servicetask1" name="Service Task" activiti:class="org.crazyit.act.c10.ForeachDelegate">
<multiInstanceLoopCharacteristics isSequential="false" activiti:elementVariable="data">
<loopDataInputRef>datas1</loopDataInputRef>
</multiInstanceLoopCharacteristics>
</serviceTask>
>
1
2
3
4
5
6
7
8 //处理类,List集合有多少个元素就执行几次
public class ForeachDelegate implements JavaDelegate {
public void execute(DelegateExecution execution) {
System.out.println("执行服务任务: " + execution.getVariable("data"));
}
}
>设置了循环了数据,会有内置参数,例如nrOfCompletedInstances是当前执行的实例数
添加<completionCondition>${nrOfCompletedInstances >= 2}</completionCondition>
设置条件执行流程
五、流程启动与服务调用API
1、查询
查询所有
通过service获取,各个service查询类似。service.createGroupQuery().groupName("Group_1").groupType("TYPE_1").list();
分页查询service.createGroupQuery().listPage(1, 5)
查询单个service.createGroupQuery().groupName("Group_0").singleResult();
排序service.createGroupQuery().orderByGroupId().desc().orderByGroupName().asc().list()
自定义查询service.createNativeGroupQuery().
sql("SELECT * FROM ACT_ID_GROUP where NAME_ = #{name}").
parameter("name", "Group_2").list();
保存service.newGroup(id);
//新增一个执行ID值
###2、流程部署
ZIP1
2
3
4FileInputStream fis = new FileInputStream(new File("resource/datas.zip"));
ZipInputStream zis = new ZipInputStream(fis);
builder.addZipInputStream(zis);
builder.deploy();
代码生成流程模型1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39public static void main(String[] args) {
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 存储服务
RepositoryService rs = engine.getRepositoryService();
RuntimeService run = engine.getRuntimeService();
DeploymentBuilder builder = rs.createDeployment();
builder.addBpmnModel("My Process", createProcessModel());
Deployment dep = builder.deploy();
}
private static BpmnModel createProcessModel() {
// 创建BPMN模型对象
BpmnModel model = new BpmnModel();
// 创建一个流程定义
org.activiti.bpmn.model.Process process = new org.activiti.bpmn.model.Process();
model.addProcess(process);
process.setId("myProcess");
process.setName("My Process");
// 开始事件
StartEvent startEvent = new StartEvent();
startEvent.setId("startEvent");
process.addFlowElement(startEvent);
// 用户任务
UserTask userTask = new UserTask();
userTask.setName("User Task");
userTask.setId("userTask");
process.addFlowElement(userTask);
// 结束事件
EndEvent endEvent = new EndEvent();
endEvent.setId("endEvent");
process.addFlowElement(endEvent);
// 添加流程顺序
process.addFlowElement(new SequenceFlow("startEvent", "userTask"));
process.addFlowElement(new SequenceFlow("userTask", "endEvent"));
return model;
}
关闭流程部署验证1
2
3
4DeploymentBuilder builder = rs.createDeployment();
builder.addClasspathResource("error/schema_error.bpmn");
builder.disableSchemaValidation(); //关闭
builder.deploy();
查询文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 存储服务
RepositoryService rs = engine.getRepositoryService();
DeploymentBuilder builder = rs.createDeployment();
builder.addClasspathResource("my_text.txt");
Deployment dep = builder.deploy();
// 数据查询
InputStream is = rs.getResourceAsStream(dep.getId(), "my_text.txt");
int count = is.available();
byte[] contents = new byte[count];
is.read(contents);
String result = new String(contents);
//输入结果
System.out.println(result);
查询流程文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 创建流程引擎
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 得到流程存储服务对象
RepositoryService repositoryService = engine.getRepositoryService();
// 部署一份流程文件
Deployment dep = repositoryService.createDeployment()
.addClasspathResource("gen.bpmn").deploy();
// 查询流程定义
//查询流程定义实体
ProcessDefinition def = repositoryService.createProcessDefinitionQuery()
.deploymentId(dep.getId()).singleResult();
// 查询资源文件
InputStream is = repositoryService.getProcessModel(def.getId());
// 读取输入流
int count = is.available();
byte[] contents = new byte[count];
is.read(contents);
String result = new String(contents);
//输入输出结果
System.out.println(result);
查询流程图片1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 创建流程引擎
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 得到流程存储服务对象
RepositoryService repositoryService = engine.getRepositoryService();
// 部署一份流程文件与相应的流程图文件
Deployment dep = repositoryService.createDeployment()
.addClasspathResource("gen.bpmn").deploy();
// 查询流程定义
ProcessDefinition def = repositoryService.createProcessDefinitionQuery()
.deploymentId(dep.getId()).singleResult();
// 查询资源文件
InputStream is = repositoryService.getProcessDiagram(def.getId());
// 将输入流转换为图片对象
BufferedImage image = ImageIO.read(is);
// 保存为图片文件
File file = new File("resource/result.png");
if (!file.exists()) file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
ImageIO.write(image, "png", fos);
fos.close();
is.close();
删除流程部署1
2repositoryService.deleteDeployment(dep.getId());
repositoryService.deleteDeployment(dep.getId(), true); //级联删除(会删除运行实例和历史数据)
3、流程定义
自己指定流程图片1
2
3
4
5
6
7ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 存储服务
RepositoryService rs = engine.getRepositoryService();
DeploymentBuilder builder = rs.createDeployment();
builder.addClasspathResource("test2.bpmn").addClasspathResource("test2.png");
builder.deploy();
流程中止
流程被中止后是不能被重新启动的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 存储服务
RepositoryService rs = engine.getRepositoryService();
DeploymentBuilder builder = rs.createDeployment();
builder.addClasspathResource("test3.bpmn");
Deployment dep = builder.deploy();
ProcessDefinition def = rs.createProcessDefinitionQuery()
.deploymentId(dep.getId()).singleResult();
System.out.println("id: " + def.getId());
rs.suspendProcessDefinitionByKey(def.getKey());
// 将会抛出异常,因为流程定义被中止了
RuntimeService runService = engine.getRuntimeService();
runService.startProcessInstanceByKey(def.getKey());
启动流程任务权限1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 存储服务
RepositoryService rs = engine.getRepositoryService();
IdentityService is = engine.getIdentityService();
TaskService ts = engine.getTaskService();
User user = is.newUser(UUID.randomUUID().toString());
user.setFirstName("Angus");
is.saveUser(user);
DeploymentBuilder builder = rs.createDeployment();
builder.addClasspathResource("test3.bpmn");
Deployment dep = builder.deploy();
ProcessDefinition def = rs.createProcessDefinitionQuery()
.deploymentId(dep.getId()).singleResult();
rs.addCandidateStarterUser(def.getId(), user.getId());
//查询该用户有多少个流程可以启动
List<ProcessDefinition> defs = rs.createProcessDefinitionQuery().startableByUser(user.getId()).list();
for(ProcessDefinition de : defs) {
System.out.println(de.getId());
}
###4、流程任务
任务候选人(组)
多少个用户或组能看见这个任务1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
TaskService ts = engine.getTaskService();
IdentityService is = engine.getIdentityService();
// 创建任务
String taskId = UUID.randomUUID().toString();
Task task = ts.newTask(taskId);
task.setName("test");
ts.saveTask(task);
// 创建用户
String userId = UUID.randomUUID().toString();
User user = is.newUser(userId);
user.setFirstName("angus");
is.saveUser(user);
// 设置任务的候选用户组
ts.addCandidateUser(taskId, userId);
/*添加用户到组*/
//is.createMembership(userId, groupId);
List<Task> tasks = ts.createTaskQuery().taskCandidateUser(userId).list();
System.out.println(userId + " 这个用户有权限处理的任务有:");
for(Task t : tasks) {
System.out.println(t.getName());
}
任务持有人
当前处理该任务用户,一个任务只有一个持有人1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
TaskService ts = engine.getTaskService();
IdentityService is = engine.getIdentityService();
// 创建任务
String taskId = UUID.randomUUID().toString();
Task task = ts.newTask(taskId);
task.setName("test1");
ts.saveTask(task);
// 创建用户
String userId = UUID.randomUUID().toString();
User user = is.newUser(userId);
user.setFirstName("angus1");
is.saveUser(user);
// 设置任务持有人
ts.setOwner(taskId, userId);
// ts.setOwner(taskId, "e110a0a5-1314-4c0c-9ba9-142447b11dea");
// 根据用户来查询他所持有的任务
List<Task> tasks = ts.createTaskQuery().taskOwner(userId).list();
for(Task t : tasks) {
System.out.println(t.getName());
}
engine.close();
任务代理人1
2
3
4
5//任务被认领之后,其他人认领就会报错
ts.claim(taskId, user.getId());
//任务指定代理人
ts.setAssignee(taskId, user.getId());
任务完成taskService.complete(task.getId());
4、参数与附件
设置参数
a、流程配置文件设置
1
2
3
4
5
6
7<!-- process标签里面 -->
<dataObject id="personName" name="personName"
itemSubjectRef="xsd:string">
<extensionElements>
<activiti:value>Crazyit</activiti:value>
</extensionElements>
</dataObject>b、启动流程设置
1
2
3
4
5
6
7Map<String,Object> map = new HashMap<>();
Person p = new Person();
p.setId(1);
p.setName("angus");
map.put("p", p);
map.put("key", "val1");
ProcessInstance pi = runService.startProcessInstanceById(pd.getId(),map);c、服务设置
1
2runService.setVariable(execution.getId(), "key",value);
taskService.setVariable(task.getId(), "key", value);d、设置本地参数
setVariable变成setVariableLocal
获取参数值1
2runService.getVariable(execution.getId(), "key");
taskService.getVariable(task.getId(), "key");
附件
5、启动流程
1 | //通过ID启动并设置business_key参数 |
6、流程操作与数据查询
task流程taskService.complete(task.getId());
Receive Task流程
该task不会产生task数据,只有execution1
2
3
4
5
6
7
8
9// 启动流程
ProcessInstance pi = runService.startProcessInstanceById(pd.getId());
// 查当前的子执行流(只有一个)
Execution exe = runService.createExecutionQuery()
.processInstanceId(pi.getId()).onlyChildExecutions()
.singleResult();
System.out.println(pi.getId() + ", 当前节点:" + exe.getActivityId());
// 让它往前走
runService.trigger(exe.getId());
7、JOB
手动执行任务(act_run_job)1
2
3
4Job job = managementService.createJobQuery().singleResult();
//设置重试次数
managementService.setJobRetries(job.getId(), 1);
managementService.executeJob(job.getId());
六、其他
6.0版本支持activiti:candidateGroups=”${prd_add}”
5.X版本只能activiti:candidateGroups=”#{prd_add}”