前面学习了三个重要的核心API,本章介绍剩下的几个核心API
流程引擎提供了身份管理服务(IdentityService)来管理用户(User),管理用户组(Group),以及用户和用户组之间的关系(Membership)。身份管理不依赖与流程定义文件。
身份管理服务调用的实现调用过程如下图
建立一个测试leiIdentityServiceTest.java
public class IdentityServiceTest {
private static final Logger logger = LoggerFactory.getLogger(IdentityServiceTest.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
//identity不依赖流程定义文件
@Test
public void testIdentity() {
//获取身份管理服务
IdentityService identityService = activitiRule.getIdentityService();
User user1 = identityService.newUser("user1");
user1.setEmail("[email protected]");
User user2 = identityService.newUser("user2");
user2.setEmail("[email protected]");
identityService.saveUser(user1);
identityService.saveUser(user2);
Group group1 = identityService.newGroup("group1");
identityService.saveGroup(group1);
Group group2 = identityService.newGroup("group2");
identityService.saveGroup(group2);
identityService.createMembership("user1", "group1");
identityService.createMembership("user2", "group1");
identityService.createMembership("user1", "group2");
List userList = identityService.createUserQuery().memberOfGroup("group1").listPage(0, 100);
for (User user : userList) {
logger.info("user = {}", ToStringBuilder.reflectionToString(user, ToStringStyle.JSON_STYLE));
}
List groupList = identityService.createGroupQuery().groupMember("user1").listPage(0, 100);
for (Group group : groupList) {
logger.info(" group = {}", ToStringBuilder.reflectionToString(group, ToStringStyle.JSON_STYLE));
}
}
}
执行结果
第一个红框看到可以查询出属于group1的两个用户,第二个红框看到查询出user1输的用户组
修改上面的测试代码,加入如下修改用户的内容
修改lastname后,我们看到version也变为2
Activiti提供了表单管理服务,主要提供了如下功能:解析流程定义中单项的配置,提交表单的方式驱动用户节点流转,获取自定义外部表单key。主要是对流程定义文件中的表单设置项进行解析
在这个例子中,创建一个带有表单的流程定义文件
public class FormServiceTest {
private static final Logger logger = LoggerFactory.getLogger(FormServiceTest.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
@Test
@Deployment(resources = {"my-process-form.bpmn20.xml"})
public void testFormService() {
FormService formService = activitiRule.getFormService();
//获取流程定义文件
ProcessDefinition processDefinition = activitiRule.getRepositoryService().createProcessDefinitionQuery().singleResult();
//获取start节点的formkey
String startFormKey = formService.getStartFormKey(processDefinition.getId());
logger.info("startFormKey = {} ", startFormKey);
//获取start节点表单数据
StartFormData startFormData = formService.getStartFormData(processDefinition.getId());
//表单数据项的遍历
List formProperties = startFormData.getFormProperties();
for (FormProperty formProperty : formProperties) {
logger.info("formProperty = {}", ToStringBuilder.reflectionToString(formProperty, ToStringStyle.JSON_STYLE));
}
//通过fromservice启动流程引擎
Map properties= Maps.newHashMap();
properties.put("message", "my test message"); //因为在定义文件中有message属性,所以这里进行赋值
formService.submitStartFormData(processDefinition.getId(), properties);
Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
TaskFormData taskFormData = formService.getTaskFormData(task.getId());
List taskFormDataFormProperties = taskFormData.getFormProperties();
for (FormProperty taskFormDataFormProperty : taskFormDataFormProperties) {
logger.info("taskFormDataFormProperty = {}", ToStringBuilder.reflectionToString(taskFormDataFormProperty,ToStringStyle.JSON_STYLE));
}
//给task的表单属性赋值
Map properties2= Maps.newHashMap();
properties2.put("yesORno", "no"); //因为在定义文件中task有yesORno属性,所以这里进行赋值
formService.submitTaskFormData(task.getId(), properties2);
Task task1 = activitiRule.getTaskService().createTaskQuery().singleResult();
logger.info("task1 = {}", task1);
}
}
历史管理服务主要提供了一下功能:管理流程实例结束后的历史数据,构建历史数据的查询对象,根据流程实例id删除流程历史数据。主要是牵涉到一下历史数据实体:
HistoricProcessInstance:历史流程实例实体类
HistoricVariableInstance:流程或任务变量值的实体
HistoricActivityInstance:单个活动节点执行的信息
HistoricTaskiInstance:用户任务实例的信息
HistoricDetail:历史流程活动任务详细信息
在这个测试类中,将通过HistroyService获取各种历史数据
public class HistoryServiceTest {
private static final Logger logger = LoggerFactory.getLogger(HistoryServiceTest.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule("activiti-history.cfg.xml");
@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testHistoryService() {
HistoryService historyService = activitiRule.getHistoryService();
//用builder可以对两类变量进行测试
ProcessInstanceBuilder processInstanceBuilder = activitiRule.getRuntimeService().createProcessInstanceBuilder();
//普通变量
Map variables = Maps.newHashMap();
variables.put("key0", "value0");
variables.put("key1","value1");
variables.put("key2","value2");
//瞬时变量
Map transientVariables = Maps.newHashMap();
transientVariables.put("tkey1","tvalue1");
//启动流程
ProcessInstance processInstance = processInstanceBuilder.processDefinitionKey("my-process")
.variables(variables)
.transientVariables(transientVariables).start();
//启动后,会暂停在task上,这个时候,我们可以用runtimeService进行变量修改
activitiRule.getRuntimeService().setVariable(processInstance.getId(),"key1", "value1-1");
//获取task
Task task = activitiRule.getTaskService().createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
//让task通过
// activitiRule.getTaskService().complete(task.getId(),variables); //可以用这种方式让task完成,本例中采用另外一种方式
//通过表单submit的方式让task通过,先获取表单,然后调用submit
Map properties= Maps.newHashMap();
properties.put("fkey1", "fvalue1");
properties.put("key2", "value2-2");
activitiRule.getFormService().submitTaskFormData(task.getId(), properties);
//通过history查询流程实例对象
List historicProcessInstances = historyService.createHistoricProcessInstanceQuery().listPage(0,100);
for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
logger.info(" historicProcessInstance = {}", ToStringBuilder.reflectionToString( historicProcessInstance,ToStringStyle.JSON_STYLE));
}
//查询节点
List historicActivityInstances = historyService.createHistoricActivityInstanceQuery().listPage(0, 100);
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
logger.info(" historicActivityInstance = {}", historicActivityInstance);
}
//查询task
List historicTaskInstances = historyService.createHistoricTaskInstanceQuery().listPage(0, 100);
for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
logger.info(" historicTaskInstance = {}", ToStringBuilder.reflectionToString(historicTaskInstance, ToStringStyle.JSON_STYLE));
}
//查询variable
List historicVariableInstances = historyService.createHistoricVariableInstanceQuery().listPage(0, 100);
for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
logger.info(" historicVariableInstance = {}", historicVariableInstance);
}
//查询details
List historicDetails = historyService.createHistoricDetailQuery().listPage(0, 100);
for (HistoricDetail historicDetail : historicDetails) {
logger.info(" historicDetail = {}", ToStringBuilder.reflectionToString(historicDetail, ToStringStyle.JSON_STYLE) );
}
//查询his log,通过include控制查询的内容
ProcessInstanceHistoryLog processInstanceHistoryLog = historyService.createProcessInstanceHistoryLogQuery(processInstance.getId())
.includeActivities()
.includeComments()
.includeVariables()
.includeFormProperties()
.includeTasks()
.includeVariableUpdates().singleResult();
List historicDataList = processInstanceHistoryLog.getHistoricData();
for (HistoricData historicData : historicDataList) {
logger.info(" historicData = {}", ToStringBuilder.reflectionToString(historicData, ToStringStyle.JSON_STYLE));
}
//删除流程历史记录
historyService.deleteHistoricProcessInstance(processInstance.getId());
//验证删除后的历史记录无法为空 期望为null
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().singleResult();
logger.info(" After delete, historicProcessInstance = {} ", historicProcessInstance);
}
ManagementService是管理服务,可以进行job任务管理,数据库相关通用操作,自定义sql查询,可以执行流程引擎名利(Command)。
在流程定义中,我们配置一个job
另外,我们还需要在cfg文件中,添加一个异步动作的配置
建立一个测试类ManagementServiceTest,在这个类里面,建立如下测试函数
@Test
@Deployment(resources = {"my-process-job.bpmn20.xml"})
public void testJobQuery() {
ManagementService managementService = activitiRule.getManagementService();
List jobs = managementService.createTimerJobQuery().listPage(0, 100);
for (Job job : jobs) {
logger.info("timeJob = {}", job);
}
JobQuery jobQuery = managementService.createJobQuery();
SuspendedJobQuery suspendedJobQuery = managementService.createSuspendedJobQuery();
List jobs1 = suspendedJobQuery.listPage(0,100);
for (Job job : jobs1) {
logger.info("suspend job = {}", job);
}
DeadLetterJobQuery deadLetterJobQuery = managementService.createDeadLetterJobQuery();
List jobs2 = deadLetterJobQuery.listPage(0, 100);
for (Job job : jobs2) {
logger.info("dead job = {}", job);
}
}
@Test
@Deployment(resources = {"my-process-job.bpmn20.xml"})
public void testTablePageQuery() {
ManagementService managementService = activitiRule.getManagementService();
TablePage tablePage = managementService.createTablePageQuery()
.tableName(managementService.getTableName(ProcessDefinitionEntity.class))
.listPage(0, 100);
List
4.4.1、定义mapper接口
数据库sql操作,需要先定义个mapper接口
package com.study.activiti.mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
public interface MyCustomMapper
{
@Select("SELECT * from ACT_RU_TASK")
public List
将这个接口在cfg文件配置进去
@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testTablePageQuery() {
//启动流程
activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
//查询task表中内容 表ACT_RU_TASK, 在mapper中定义的sql
ManagementService managementService = activitiRule.getManagementService();
List
@Test
@Deployment(resources = {"my-process.bpmn20.xml"})
public void testCommand() {
//启动流程
activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
//获取management
ManagementService managementService = activitiRule.getManagementService();
//执行execute
ProcessDefinitionEntity processDefinitionEntity = managementService.executeCommand(new Command() {
@Override
public ProcessDefinitionEntity execute(CommandContext commandContext) {
ProcessDefinitionEntity processDefinitionEntity = commandContext.getProcessDefinitionEntityManager()
.findLatestProcessDefinitionByKey("my-process");
return processDefinitionEntity;
}
});
logger.info("processDefinitionEntity = {}", processDefinitionEntity);
}
DynamicBpmnService是6.0以后才有的动态流程定义服务,但是不建议使用,因为这个是对业务进行强制修改,容易引发混乱,建议少用