activiti学习(⼗九)——流程虚拟机源码分析(⼀)——流程
启动源码分析
从这篇⽂章开始,将从源码分析流程虚拟机的运转情况。本⽂主要讲讲流程启动相关的。流程虚拟机的调⽤与运转,跟前⾯对象解析器解析与设置是息息相关的。我看代码的时候,也常常需要来回翻阅对象解析器的设置。流程虚拟机在调⽤某个对象时,这个对象到底是什么,常常让我感到困惑。所以我决定⼀步⼀步进⾏梳理。
流程启动⼊⼝
上图是调⽤RuntimeService的startProcessInstanceById⽅法开始启动流程的活动图。⾸先通过传⼊的参数获取部署时⽣成的流程定义,通过流程定义⽣成执⾏实体类,并且设置流程变量,该ExecutionEntity即对应数据库ACT_RU_EXECUTION表。第10步通过原⼦操作类开始流程虚拟机的运转。第10步涉及的内容⽐较多,后⾯再详细叙述。
下⾯来看源码,从RuntimeService调⽤startProcessInstanceById,执⾏StartProcessInstanceCmd的execution⽅法开始:
public class StartProcessInstanceCmd<T> implements Command<ProcessInstance>, Serializable {
//......
public ProcessInstance execute(CommandContext commandContext) {
DeploymentManager deploymentManager = commandContext
.getProcessEngineConfiguration()
.getDeploymentManager();
ProcessDefinitionEntity processDefinition = null;
if (processDefinitionId != null) {
processDefinition = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);
if (processDefinition == null) {
throw new ActivitiObjectNotFoundException("No process definition found for id = '" + processDefinitionId + "'", ProcessDefinition.class);
}
} else if {
//......其他⽅法获取流程定义
} else {
throw new ActivitiIllegalArgumentException("processDefinitionKey and processDefinitionId are null");
}
//......
ExecutionEntity processInstance = ateProcessInstance(businessKey);
initializeVariables(processInstance);
if (processInstanceName != null) {
processInstance.setName(processInstanceName);
}
processInstance.start();
return processInstance;
}
6-8⾏获取部署管理类。10-21⾏根据流程定义id获取部署流程图时⽣成的流程定义。23⾏创建执⾏实体类。24⾏为执⾏实体类设置流程变量。31⾏开始执⾏实体类。
接着看23⾏如何创建执⾏实体类,跟踪ProcessDefinitionEntity类:
public class ProcessDefinitionEntity extends ProcessDefinitionImpl implements ProcessDefinition, PersistentObject, HasRevision {
//......
public ExecutionEntity createProcessInstance(String businessKey, ActivityImpl initial) {
ExecutionEntity processInstance = null;
if(initial == null) {
processInstance = (ExecutionEntity) ateProcessInstance();
}else {
processInstance = (ExecutionEntity) ateProcessInstanceForInitial(initial);
}
//processInstances属性设置
.recordProcessInstanceStart(processInstance);
if (ProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
}
return processInstance;
}
public ExecutionEntity createProcessInstance(String businessKey) {
return createProcessInstance(businessKey, null);
}
/
/......
}
⾸先会调⽤29⾏的createProcessInstance,然后到第5⾏。启动时我们的initial为null,因此调⽤第9⾏。14-22的代码包括属性设置、触发全局事件转发、历史表记录等。第5⾏调⽤了超类ProcessDefinitionImpl的createProcessInstance⽅法,下⾯跟踪ProcessDefinitionImpl类:
public class ProcessDefinitionImpl extends ScopeImpl implements PvmProcessDefinition {
protected ActivityImpl initial;
//......
public PvmProcessInstance createProcessInstance() {
if(initial == null) {
//抛出异常
}
return createProcessInstanceForInitial(initial);
}
public PvmProcessInstance createProcessInstanceForInitial(ActivityImpl initial) {
if(initial == null) {
throw new ActivitiException("Cannot start process instance, initial activity where the process instance should start is null.");
}
InterpretableExecution processInstance = newProcessInstance(initial);
processInstance.setProcessDefinition(this);
processInstance.setProcessInstance(processInstance);
processInstance.initialize();
InterpretableExecution scopeInstance = processInstance;
List<ActivityImpl> initialActivityStack = getInitialActivityStack(initial);
for (ActivityImpl initialActivity: initialActivityStack) {
if (initialActivity.isScope()) {
scopeInstance = (InterpretableExecution) ateExecution();
scopeInstance.setActivity(initialActivity);
if (initialActivity.isScope()) {
scopeInstance.initialize();
}createprocessa
}
}
scopeInstance.setActivity(initial);
return processInstance;
}
//......
}
进来第6⾏的createProcessInstance⽅法。第7⾏判断的initial是在对象解析阶段设置的startEvent,不了解的同学可以查阅StartEventParseHandler类的executeParse⽅法中调⽤的selectInitial。第7⾏的判断如果流程开始不存在startEvent那么流程就⽆法开始了,只能抛出异常。19⾏调⽤newProcessInstance,注意这⾥⽤到了多态,实际上调⽤的是ProcessDefinitionEntity的newProcessInstance⽅法创建ExecutionEntity,⽽不是调⽤ProcessDefinitionImpl的newProcessInstance创建ExecutionImpl。26⾏把startEvent保存到initialActivityStack中,⽅便管理。38⾏执⾏实体类当前的活动为startEvent。
到此为⽌,上⾯⼀系列的操作成功创建了执⾏实体类,并设置了当前活动为startEvent。下⼀步的⼯作是通过原⼦操作类使流程虚拟机运转起来,并执⾏startEvent的“⾏为”。
流程实例启动
在StartProcessInstanceCmd的execution最后,代码执⾏processInstance.start()启动流程实例,此时跳到ExecutionEntity的start⽅法
public class ExecutionEntity extends VariableScopeImpl implements ActivityExecution, ExecutionListenerExecution, Execution, PvmExecution,
ProcessInstance, InterpretableExecution, PersistentObject, HasRevision {
//......
public void start() {
if(startingExecution == null && isProcessInstanceType()) {
startingExecution = new Initial());
}
performOperation(AtomicOperation.PROCESS_START);
}
public void performOperation(AtomicOperation executionOperation) {
if (executionOperation.isAsync(this)) {
scheduleAtomicOperationAsync(executionOperation);
} else {
performOperationSync(executionOperation);
}
}
protected void performOperationSync(AtomicOperation executionOperation) {
Context
.getCommandContext()
.performOperation(executionOperation, this);
}
//......
}
第10⾏执⾏performOperation,参数是AtomicOperation.PROCESS_START,这属于原⼦类操作,我们⼀会讲。接着调⽤13-19⾏,根据流程⽂档⾥⾯设置的,判断是异步执⾏还是同步执⾏,这⾥我们先按同步执⾏去跟踪。紧接着调⽤CommandContext的performOperation⽅法。
public class CommandContext {
//......
public void performOperation(AtomicOperation executionOperation, InterpretableExecution execution) {
nextOperations.add(executionOperation);
if (nextOperations.size()==1) {
try {
Context.setExecutionContext(execution);
while (!nextOperations.isEmpty()) {
AtomicOperation currentOperation = veFirst();
if (log.isTraceEnabled()) {
}
if (ReplacedBy() == null) {
} else {
}
}
} finally {
}
}
}
//......
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论