流程定義和部署管理——啟用、掛起
阿新 • • 發佈:2019-02-14
我們之前已經看了流程定義列表頁面process-list.jsp和執行流程列表頁面running-manage.jsp,這兩個頁面都有啟用和掛起,那麼有什麼不同呢?
首先是流程定義掛起的url
http://localhost:8080/kft-activiti-demo-no-maven/workflow/processdefinition/update/suspend/leave:1:20
其次是流程例項掛起的url
http://localhost:8080/kft-activiti-demo-no-maven/workflow/processinstance/update/suspend/14
從現象上看,當流程定義啟用或者掛起時,對應的流程執行例項的suspended狀態會跟著改變;
當流程執行例項啟用或者掛起時,對應的流程定義的suspended狀態不會跟著改變。
一、流程定義的啟用、掛起
ActivitiController中:
/** * 掛起、啟用流程定義 */ @RequestMapping(value = "processdefinition/update/{state}/{processDefinitionId}") public String updateState(@PathVariable("state") String state, @PathVariable("processDefinitionId") String processDefinitionId, RedirectAttributes redirectAttributes) { if (state.equals("active")) { redirectAttributes.addFlashAttribute("message", "已啟用ID為[" + processDefinitionId + "]的流程定義。"); repositoryService.activateProcessDefinitionById(processDefinitionId, true, null); } else if (state.equals("suspend")) { repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null); redirectAttributes.addFlashAttribute("message", "已掛起ID為[" + processDefinitionId + "]的流程定義。"); } return "redirect:/workflow/process-list"; }
請注意suspendProcessDefinitionById和activateProcessDefinitionById方法的第二個引數,我們來看一下RepositoryServiceImpl中這個方法的定義:
public void suspendProcessDefinitionById(String processDefinitionId, boolean suspendProcessInstances, Date suspensionDate) { this.commandExecutor.execute(new SuspendProcessDefinitionCmd(processDefinitionId, null, suspendProcessInstances, suspensionDate, null)); }
原來它就是用來控制在掛起流程定義時,是否同時掛起對應的流程例項。
public class SuspendProcessDefinitionCmd extends AbstractSetProcessDefinitionStateCmd
{
public SuspendProcessDefinitionCmd(String processDefinitionId, String processDefinitionKey, boolean suspendProcessInstances, Date suspensionDate, String tenantId)
{
super(processDefinitionId, processDefinitionKey, suspendProcessInstances, suspensionDate, tenantId);
}
}
public abstract class AbstractSetProcessDefinitionStateCmd
implements Command<Void>
{
public AbstractSetProcessDefinitionStateCmd(String processDefinitionId, String processDefinitionKey, boolean includeProcessInstances, Date executionDate, String tenantId)
{
this.processDefinitionId = processDefinitionId;
this.processDefinitionKey = processDefinitionKey;
this.includeProcessInstances = includeProcessInstances;
this.executionDate = executionDate;
this.tenantId = tenantId;
}
public Void execute(CommandContext commandContext)
{
List processDefinitions = findProcessDefinition(commandContext);
if (this.executionDate != null)
createTimerForDelayedExecution(commandContext, processDefinitions);
else {
changeProcessDefinitionState(commandContext, processDefinitions);
}
return null;
}
protected void changeProcessDefinitionState(CommandContext commandContext, List<ProcessDefinitionEntity> processDefinitions) {
for (ProcessDefinitionEntity processDefinition : processDefinitions)
{
SuspensionState.SuspensionStateUtil.setSuspensionState(processDefinition, getProcessDefinitionSuspensionState());
commandContext.getProcessEngineConfiguration().getDeploymentManager().getProcessDefinitionCache().remove(processDefinition.getId());
if (this.includeProcessInstances)
{
int currentStartIndex = 0;
List processInstances = fetchProcessInstancesPage(commandContext, processDefinition, currentStartIndex);
while (processInstances.size() > 0)
{
for (ProcessInstance processInstance : processInstances) {
AbstractSetProcessInstanceStateCmd processInstanceCmd = getProcessInstanceChangeStateCmd(processInstance);
processInstanceCmd.execute(commandContext);
}
currentStartIndex += processInstances.size();
processInstances = fetchProcessInstancesPage(commandContext, processDefinition, currentStartIndex);
}
}
}
}
}
activateProcessDefinitionById呼叫層次類似,不重複。
二、流程例項的啟用、掛起
ProcessInstanceController中:
/**
* 掛起、啟用流程例項
*/
@RequestMapping(value = "update/{state}/{processInstanceId}")
public String updateState(@PathVariable("state") String state, @PathVariable("processInstanceId") String processInstanceId,
RedirectAttributes redirectAttributes) {
if (state.equals("active")) {
redirectAttributes.addFlashAttribute("message", "已啟用ID為[" + processInstanceId + "]的流程例項。");
runtimeService.activateProcessInstanceById(processInstanceId);
} else if (state.equals("suspend")) {
runtimeService.suspendProcessInstanceById(processInstanceId);
redirectAttributes.addFlashAttribute("message", "已掛起ID為[" + processInstanceId + "]的流程例項。");
}
return "redirect:/workflow/processinstance/running";
}
這個就暫時沒有過多介紹了,就看一下RuntimeServiceImpl中的實現
public void suspendProcessInstanceById(String processInstanceId) {
this.commandExecutor.execute(new SuspendProcessInstanceCmd(processInstanceId));
}
public void activateProcessInstanceById(String processInstanceId) {
this.commandExecutor.execute(new ActivateProcessInstanceCmd(processInstanceId));
}
public class SuspendProcessInstanceCmd extends AbstractSetProcessInstanceStateCmd
{
public SuspendProcessInstanceCmd(String executionId)
{
super(executionId);
}
}
public abstract class AbstractSetProcessInstanceStateCmd
implements Command<Void>
{
protected final String executionId;
public AbstractSetProcessInstanceStateCmd(String executionId)
{
this.executionId = executionId;
}
public Void execute(CommandContext commandContext)
{
if (this.executionId == null) {
throw new ActivitiIllegalArgumentException("ProcessInstanceId cannot be null.");
}
ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findExecutionById(this.executionId);
if (executionEntity == null) {
throw new ActivitiObjectNotFoundException("Cannot find processInstance for id '" + this.executionId + "'.", Execution.class);
}
if (!executionEntity.isProcessInstanceType()) {
throw new ActivitiException("Cannot set suspension state for execution '" + this.executionId + "': not a process instance.");
}
SuspensionState.SuspensionStateUtil.setSuspensionState(executionEntity, getNewState());
List childExecutions = commandContext.getExecutionEntityManager().findChildExecutionsByProcessInstanceId(this.executionId);
for (ExecutionEntity childExecution : childExecutions) {
if (!childExecution.getId().equals(this.executionId)) {
SuspensionState.SuspensionStateUtil.setSuspensionState(childExecution, getNewState());
}
}
List tasks = commandContext.getTaskEntityManager().findTasksByProcessInstanceId(this.executionId);
for (TaskEntity taskEntity : tasks) {
SuspensionState.SuspensionStateUtil.setSuspensionState(taskEntity, getNewState());
}
return null;
}
protected abstract SuspensionState getNewState();
}