前面學習了三個重要的核心API,本章介紹剩下的幾個核心API
1、身份管理服務
流程引擎提供了身份管理服務(IdentityService)來管理用戶(User),管理用戶組(Group),以及用戶和用戶組之間的關係(Membership)。身份管理不依賴與流程定義文件。
身份管理服務調用的實現調用過程如下圖
1.1、創建用戶和組
建立一個測試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<User> userList = identityService.createUserQuery().memberOfGroup("group1").listPage(0, 100);
for (User user : userList) {
logger.info("user = {}", ToStringBuilder.reflectionToString(user, ToStringStyle.JSON_STYLE));
}
List<Group> groupList = identityService.createGroupQuery().groupMember("user1").listPage(0, 100);
for (Group group : groupList) {
logger.info(" group = {}", ToStringBuilder.reflectionToString(group, ToStringStyle.JSON_STYLE));
}
}
}
執行結果
第一個紅框看到可以查詢出屬於group1的兩個用戶,第二個紅框看到查詢出user1輸的用戶組
1.2、修改用戶組
修改上面的測試代碼,加入如下修改用戶的內容
1.3、執行結果
修改lastname後,我們看到version也變爲2
2、表單管理服務
Activiti提供了表單管理服務,主要提供瞭如下功能:解析流程定義中單項的配置,提交表單的方式驅動用戶節點流轉,獲取自定義外部表單key。主要是對流程定義文件中的表單設置項進行解析
2.1、創建流程定義文件
在這個例子中,創建一個帶有表單的流程定義文件
2.2、創建FormServiceTest
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<FormProperty> formProperties = startFormData.getFormProperties();
for (FormProperty formProperty : formProperties) {
logger.info("formProperty = {}", ToStringBuilder.reflectionToString(formProperty, ToStringStyle.JSON_STYLE));
}
//通過fromservice啓動流程引擎
Map<String, String> 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<FormProperty> taskFormDataFormProperties = taskFormData.getFormProperties();
for (FormProperty taskFormDataFormProperty : taskFormDataFormProperties) {
logger.info("taskFormDataFormProperty = {}", ToStringBuilder.reflectionToString(taskFormDataFormProperty,ToStringStyle.JSON_STYLE));
}
//給task的表單屬性賦值
Map<String, String> properties2= Maps.newHashMap();
properties2.put("yesORno", "no"); //因爲在定義文件中task有yesORno屬性,所以這裏進行賦值
formService.submitTaskFormData(task.getId(), properties2);
Task task1 = activitiRule.getTaskService().createTaskQuery().singleResult();
logger.info("task1 = {}", task1);
}
}
2.3、執行結果
3、歷史管理服務
歷史管理服務主要提供了一下功能:管理流程實例結束後的歷史數據,構建歷史數據的查詢對象,根據流程實例id刪除流程歷史數據。主要是牽涉到一下歷史數據實體:
HistoricProcessInstance:歷史流程實例實體類
HistoricVariableInstance:流程或任務變量值的實體
HistoricActivityInstance:單個活動節點執行的信息
HistoricTaskiInstance:用戶任務實例的信息
HistoricDetail:歷史流程活動任務詳細信息
3.1、創建測試類HistoryServiceTest
在這個測試類中,將通過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<String, Object> variables = Maps.newHashMap();
variables.put("key0", "value0");
variables.put("key1","value1");
variables.put("key2","value2");
//瞬時變量
Map<String, Object> 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<String, String> properties= Maps.newHashMap();
properties.put("fkey1", "fvalue1");
properties.put("key2", "value2-2");
activitiRule.getFormService().submitTaskFormData(task.getId(), properties);
//通過history查詢流程實例對象
List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery().listPage(0,100);
for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
logger.info(" historicProcessInstance = {}", ToStringBuilder.reflectionToString( historicProcessInstance,ToStringStyle.JSON_STYLE));
}
//查詢節點
List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery().listPage(0, 100);
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
logger.info(" historicActivityInstance = {}", historicActivityInstance);
}
//查詢task
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().listPage(0, 100);
for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
logger.info(" historicTaskInstance = {}", ToStringBuilder.reflectionToString(historicTaskInstance, ToStringStyle.JSON_STYLE));
}
//查詢variable
List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery().listPage(0, 100);
for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
logger.info(" historicVariableInstance = {}", historicVariableInstance);
}
//查詢details
List<HistoricDetail> 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<HistoricData> 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);
}
3.2、執行結果
4、管理服務
ManagementService是管理服務,可以進行job任務管理,數據庫相關通用操作,自定義sql查詢,可以執行流程引擎名利(Command)。
4.1、流程定義
在流程定義中,我們配置一個job
另外,我們還需要在cfg文件中,添加一個異步動作的配置
4.2、查找JOB
4.2.1、建立測試函數testJobQuery
建立一個測試類ManagementServiceTest,在這個類裏面,建立如下測試函數
@Test
@Deployment(resources = {"my-process-job.bpmn20.xml"})
public void testJobQuery() {
ManagementService managementService = activitiRule.getManagementService();
List<Job> jobs = managementService.createTimerJobQuery().listPage(0, 100);
for (Job job : jobs) {
logger.info("timeJob = {}", job);
}
JobQuery jobQuery = managementService.createJobQuery();
SuspendedJobQuery suspendedJobQuery = managementService.createSuspendedJobQuery();
List<Job> jobs1 = suspendedJobQuery.listPage(0,100);
for (Job job : jobs1) {
logger.info("suspend job = {}", job);
}
DeadLetterJobQuery deadLetterJobQuery = managementService.createDeadLetterJobQuery();
List<Job> jobs2 = deadLetterJobQuery.listPage(0, 100);
for (Job job : jobs2) {
logger.info("dead job = {}", job);
}
}
4.2.2、執行日誌
4.3、數據庫表查詢
4.3.1、測試代碼
@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<Map<String, Object>> rows = tablePage.getRows();
for (Map<String, Object> row : rows) {
logger.info("row = {}", row);
}
}
4.3.2 執行結果
4.4、數據庫sql操作
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<Map<String, Object>> findAll();
}
4.4.2、cfg文件配置mapper對象
將這個接口在cfg文件配置進去
4.4.3、測試代碼
@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<Map<String, Object>> mapList = managementService.executeCustomSql(new AbstractCustomSqlExecution<MyCustomMapper,
List<Map<String, Object>>>(MyCustomMapper.class) {
@Override
public List<Map<String, Object>> execute(MyCustomMapper o) {
return o.findAll();
}
});
for (Map<String, Object> map : mapList) {
logger.info(" map = {}", map);
}
}
4.4.4、執行日誌:
4.5、執行命令
4.5.1、測試代碼
@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<ProcessDefinitionEntity>() {
@Override
public ProcessDefinitionEntity execute(CommandContext commandContext) {
ProcessDefinitionEntity processDefinitionEntity = commandContext.getProcessDefinitionEntityManager()
.findLatestProcessDefinitionByKey("my-process");
return processDefinitionEntity;
}
});
logger.info("processDefinitionEntity = {}", processDefinitionEntity);
}
4.5.2、執行日誌:
5、動態流程定義服務
DynamicBpmnService是6.0以後纔有的動態流程定義服務,但是不建議使用,因爲這個是對業務進行強制修改,容易引發混亂,建議少用