Activiti 流程启动及节点流转源代码分析
作者:jiankunking 出处:http://blog.csdn.net/jiankunking
本文主要是以activiti-study中的xiaomage.xml流程图为例进行跟踪分析
详细的流程图例如以下:
流程图相应的XML文件例如以下:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="MyProcess" name="MyProcess">
<documentation>Place documentation for the 'MyProcess' process here.</documentation>
<startEvent id="startevent1" name="Start"/>
<userTask id="sss" name="ddd" activiti:assignee="fq"/>
<sequenceFlow id="flow1" name="" sourceRef="startevent1" targetRef="sss"/>
<endEvent id="endevent1" name="End"/>
<sequenceFlow id="flow2" name="" sourceRef="sss" targetRef="endevent1"/>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_MyProcess">
<bpmndi:BPMNPlane bpmnElement="MyProcess" id="BPMNPlane_MyProcess">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35" width="35" x="340" y="150"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sss" id="BPMNShape_sss">
<omgdc:Bounds height="55" width="105" x="305" y="250"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35" width="35" x="340" y="370"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="357" y="185"/>
<omgdi:waypoint x="357" y="250"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="357" y="305"/>
<omgdi:waypoint x="357" y="370"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
流程实例创建步骤例如以下(下图转载自:activiti 源代码笔记之startProcess):
流程启动跟踪分析:
图一:
图二:
图三:
图四:
以上主要是跟踪分析了,三个节点之间的流转情况。
在流转的时候须要注意下面两个接口:
原子操作(AtomicOperation)接口:
public interface AtomicOperation {
AtomicOperation PROCESS_START = new AtomicOperationProcessStart();
AtomicOperation PROCESS_START_INITIAL = new AtomicOperationProcessStartInitial();
AtomicOperation PROCESS_END = new AtomicOperationProcessEnd();
AtomicOperation ACTIVITY_START = new AtomicOperationActivityStart();
AtomicOperation ACTIVITY_EXECUTE = new AtomicOperationActivityExecute();
AtomicOperation ACTIVITY_END = new AtomicOperationActivityEnd();
AtomicOperation TRANSITION_NOTIFY_LISTENER_END = new AtomicOperationTransitionNotifyListenerEnd();
AtomicOperation TRANSITION_DESTROY_SCOPE = new AtomicOperationTransitionDestroyScope();
AtomicOperation TRANSITION_NOTIFY_LISTENER_TAKE = new AtomicOperationTransitionNotifyListenerTake();
AtomicOperation TRANSITION_CREATE_SCOPE = new AtomicOperationTransitionCreateScope();
AtomicOperation TRANSITION_NOTIFY_LISTENER_START = new AtomicOperationTransitionNotifyListenerStart();
AtomicOperation DELETE_CASCADE = new AtomicOperationDeleteCascade();
AtomicOperation DELETE_CASCADE_FIRE_ACTIVITY_END = new AtomicOperationDeleteCascadeFireActivityEnd();
void execute(InterpretableExecution execution);
boolean isAsync(InterpretableExecution execution);
}
注意:
void execute(InterpretableExecution execution);
InterpretableExecution接口:
public interface InterpretableExecution extends ActivityExecution, ExecutionListenerExecution, PvmProcessInstance {
void take(PvmTransition transition);
void take(PvmTransition transition, boolean fireActivityCompletedEvent);
void setEventName(String eventName);
void setEventSource(PvmProcessElement element);
Integer getExecutionListenerIndex();
void setExecutionListenerIndex(Integer executionListenerIndex);
ProcessDefinitionImpl getProcessDefinition();
void setActivity(ActivityImpl activity);
void performOperation(AtomicOperation etomicOperation);
boolean isScope();
void destroy();
void remove();
InterpretableExecution getReplacedBy();
void setReplacedBy(InterpretableExecution replacedBy);
InterpretableExecution getSubProcessInstance();
void setSubProcessInstance(InterpretableExecution subProcessInstance);
InterpretableExecution getSuperExecution();
void deleteCascade(String deleteReason);
boolean isDeleteRoot();
TransitionImpl getTransition();
void setTransition(TransitionImpl object);
void initialize();
void setParent(InterpretableExecution parent);
void setProcessDefinition(ProcessDefinitionImpl processDefinitionImpl);
void setProcessInstance(InterpretableExecution processInstance);
boolean isEventScope();
void setEventScope(boolean isEventScope);
StartingExecution getStartingExecution();
void disposeStartingExecution();
}
注意:
void performOperation(AtomicOperation etomicOperation);
单独摘出来的两个方法是图一中:
上下文、原子操作、运行器实体三者相互调用的关键。
上图的详细调用情况例如以下:
ExecutionEntity类中的:
public void performOperation(AtomicOperation executionOperation) {
if (executionOperation.isAsync(this)) {
scheduleAtomicOperationAsync(executionOperation);
} else {
performOperationSync(executionOperation);
}
}
protected void performOperationSync(AtomicOperation executionOperation) {
Context
.getCommandContext()
.performOperation(executionOperation, this);
}
performOperation函数中调用上下文CommandContext类中的:
public void performOperation(AtomicOperation executionOperation, InterpretableExecution execution) {
nextOperations.add(executionOperation);
if (nextOperations.size()==1) {
try {
Context.setExecutionContext(execution);
while (!nextOperations.isEmpty()) {
AtomicOperation currentOperation = nextOperations.removeFirst();
if (log.isTraceEnabled()) {
log.trace("AtomicOperation: {} on {}", currentOperation, this);
}
if (execution.getReplacedBy() == null) {
currentOperation.execute(execution);
} else {
currentOperation.execute(execution.getReplacedBy());
}
}
} finally {
Context.removeExecutionContext();
}
}
}
performOperation函数调用原子操作(AtomicOperation)接口中的void execute(InterpretableExecution execution)来处理。
该处的处理分为两种情况:
1、依据AtomicOperation接口标识来继续进行流转
(再次调用ExecutionEntity类中的performOperation(AtomicOperation executionOperation)方法)
比方:
PROCESS_START=》PROCESS_START_INITIAL=》ACTIVITY_EXECUTE。。。。
。。
详细能够參考本文图一到图四的代码跟踪中的标识。
2、依据节点上的ActivityBehavior类进行不同的处理
Activiti节点(開始、结束、任务、网关等等)都是Activity类型的,仅仅是其挂的ActivityBehavior不同。通过不同的ActivityBehavior来实现相应的操作。
作者:jiankunking 出处:http://blog.csdn.net/jiankunking