activiti学习(⼆⼗)——流程虚拟机源码分析(⼆)——从开
始节点离开到下个节点前
简述
《》⼀⽂中最后,流程从startEvent节点执⾏takeAll准备离开。本⽂我们分析⼀下从开始节点到下⼀个节点之前虚拟机做了什么。由于流程虚拟机条件分⽀情况很多,⼀⼀叙述⾮常繁琐(有些我⾃⼰理解也不透彻),所以我会⽤最简单的模型去跟踪其流转,如下图:
我们假设起点startEvent的下⼀个节点是⼀个普通的urTask,本⽂跟踪其在流程虚拟机的代码⾛向。
跟踪源码
上⼀篇⽂章我们跟踪到ExecutionEntity的takeAll⽅法。startEvent活动类通过调⽤这个⽅法离开startEvent节点。
public class ExecutionEntity extends VariableScopeImpl implements ActivityExecution, ExecutionListenerExecution, Execution, PvmExecution,
深锁
ProcessInstance, InterpretableExecution, PersistentObject, HasRevision {
//......
public void takeAll(List<PvmTransition> transitions, List<ActivityExecution> recyclableExecutions) {
fireActivityCompletedEvent();
transitions = new ArrayList<PvmTransition>(transitions);
recyclableExecutions = (recyclableExecutions!=null ? new ArrayList<ActivityExecution>(recyclableExecutions) : new ArrayList<ActivityExecution>());
if (recyclableExecutions.size()>1) {树用英语怎么说
for (ActivityExecution recyclableExecution: recyclableExecutions) {
if (((ExecutionEntity)recyclableExecution).isScope()) {
throw new PvmException("joining scope executions is not allowed");
}什么是注册制股票
}
}
六大门派
ExecutionEntity concurrentRoot = ((isConcurrent && !isScope) ? getParent() : this);
List<ExecutionEntity> concurrentActiveExecutions = new ArrayList<ExecutionEntity>();
List<ExecutionEntity> concurrentInActiveExecutions = new ArrayList<ExecutionEntity>();
for (ExecutionEntity execution: Executions()) {
if (execution.isActive()) {
concurrentActiveExecutions.add(execution);
} el {
concurrentInActiveExecutions.add(execution);
}
}
if ( (transitions.size()==1)
&& (concurrentActiveExecutions.isEmpty())
&& allExecutionsInSameActivity(concurrentInActiveExecutions)
) {
List<ExecutionEntity> recyclableExecutionImpls = (List) recyclableExecutions;
for (ExecutionEntity prunedExecution: recyclableExecutionImpls) {
for (ExecutionEntity prunedExecution: recyclableExecutionImpls) {
}
concurrentRoot.tActive(true);
concurrentRoot.tActivity(activity);
concurrentRoot.tConcurrent(fal);
concurrentRoot.(0), fal);
} el {
//......
}
public void take(PvmTransition transition, boolean fireActivityCompletionEvent) {
if (fireActivityCompletionEvent) {
fireActivityCompletedEvent();
}
if (ansition!=null) {
throw new PvmException("already taking a transition");
}
if (transition==null) {
throw new PvmException("transition is null");
}
蛋糕的英文单词
tActivity((Source());
tTransition((TransitionImpl) transition);
performOperation(AtomicOperation.TRANSITION_NOTIFY_LISTENER_END);
}
//......
}
第8⾏fireActivityCompletedEvent⽅法会触发全局事件转发器转发ACTIVITY_COMPLETED事件。11⾏由于⼊参recyclableExecutions为空,所以为recyclableExecutions新建⼀个空的数组。22⾏isConcurrent默认为fal,isScope默认是true,因此concurrentRoot赋值为this。32-34⾏判断假设startEvent的“出线”只有⼀条,则此时判断为true。48⾏通过take离开startEvent节点。66⾏设置当前活动为startEvent的ActivitiImpl,67⾏设置当前的连线,68⾏调⽤原⼦操作
performOperation(AtomicOperation.TRANSITION_NOTIFY_LISTENER_END)。这个原⼦操作的调⽤我们上⼀篇⽂章分析过,这⾥不再细述。看看AtomicOperation.TRANSITION_NOTIFY_LISTENER_END对应的AtomicOperationTransitionNotifyListenerEnd类:
public class AtomicOperationTransitionNotifyListenerEnd extends AbstractEventAtomicOperation {
//......
protected String getEventName() {
return ine.impl.pvm.PvmEvent.EVENTNAME_END;
}
protected void eventNotificationsCompleted(InterpretableExecution execution) {
execution.performOperation(TRANSITION_DESTROY_SCOPE);
}
}
这⾥原⼦操作⾸先会触发实⾏监听器的end事件,然后执⾏原⼦操作performOperation(TRANSITION_DESTROY_SCOPE)。即调⽤AtomicOperationTransitionDestroyScope类
public class AtomicOperationTransitionDestroyScope implements AtomicOperation {
//......
@SuppressWarnings("unchecked")
public void execute(InterpretableExecution execution) {
InterpretableExecution propagatingExecution = null;
ActivityImpl activity = (ActivityImpl) Activity();
if (activity.isScope()) {
//......
} el {
propagatingExecution = execution;
}
ScopeImpl nextOuterScopeElement = Parent();
TransitionImpl transition = Transition();
ActivityImpl destination = Destination();
if (transitionLeavesNextOuterScope(nextOuterScopeElement, destination)) {
propagatingExecution.tActivity((ActivityImpl) nextOuterScopeElement);
propagatingExecution.performOperation(TRANSITION_NOTIFY_LISTENER_END);
} el {
propagatingExecution.performOperation(TRANSITION_NOTIFY_LISTENER_TAKE);
}
}
public boolean transitionLeavesNextOuterScope(ScopeImpl nextScopeElement, ActivityImpl destination) {
return !ains(destination);
}
}
执⾏execution⽅法,第10⾏的if判断为fal,注意execution的isScope为true,但是ActivityImpl的isScope为fal,所以这⾥执⾏13⾏的代码。16⾏获取Parent(),即startEvent的parent,是Process对象。18⾏获取连线终点的活动。19⾏判断Process中是否含有下⼀个节点的活动,因此28⾏函数判断为fal(!符号取了相反的值),因此⾛23⾏
performOperation(TRANSITION_NOTIFY_LISTENER_TAKE),会调⽤AtomicOperationTransitionNotifyListenerTake类。
public class AtomicOperationTransitionNotifyListenerTake implements AtomicOperation {
//......
public void execute(InterpretableExecution execution) {
TransitionImpl transition = Transition();
List<ExecutionListener> executionListeners = ExecutionListeners();
int executionListenerIndex = ExecutionListenerIndex();
if (executionListeners.size()>executionListenerIndex) {
execution.tEventName(ine.impl.pvm.PvmEvent.EVENTNAME_TAKE);
execution.tEventSource(transition);
ExecutionListener listener = (executionListenerIndex);
try {
} catch (RuntimeException e) {
平均地权打一字
throw e;
} catch (Exception e) {
throw new PvmException("couldn't execute event listener : "+e.getMessage(), e);
}
execution.tExecutionListenerIndex(executionListenerIndex+1);
execution.performOperation(this);
} el {
execution.tExecutionListenerIndex(0);
execution.tEventName(null);
execution.tEventSource(null);
ActivityImpl activity = (ActivityImpl) Activity();
ActivityImpl nextScope = Parent(), Destination());
execution.tActivity(nextScope);
刘一博ProcessEngineConfiguration() != null && ProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
execution.performOperation(TRANSITION_CREATE_SCOPE);
}
}
/** finds the next scope to enter. the most outer scope is found first */
public static ActivityImpl findNextScope(ScopeImpl outerScopeElement, ActivityImpl destination) {
ActivityImpl nextScope = destination;香港置地广场
while( (Parent() instanceof ActivityImpl)
&& (Parent() != outerScopeElement)
) {
nextScope = (ActivityImpl) Parent();
}
return nextScope;
}
}
8-23⾏嵌套调⽤,遍历每⼀个执⾏监听器触发take事件。30-32⾏把execution的当前活动设置为下⼀个活动节点。34-38⾏触发全局事
件转发器SEQUENCEFLOW_TAKEN事件。从此execution进⼊下⼀个节点。
⼩结
普遍来说,流程从⼀般的活动离开,就是通过ExecutionEntity的take⽅法,然后经历数个原⼦操作,触发执⾏监听器和全局事件转发器对应的事件,如果涉及⼦流程、⽹关形成的分⽀流程等,则情况会更复杂⼀些。最后把该触发的事件都触发完毕之后,把ExecutionEntity当前的活动设置为下⼀个节点,就此进⼊下⼀个节点相关的活动中。