作者: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

Activiti 流程启动及节点流转源代码分析的更多相关文章

  1. Activiti 学习(三)—— Activiti 流程启动并完成

    Activiti 流程启动 流程定义部署后,就可以通过工作流管理业务流程了,也就是说前文部署的出差申请流程可以使用了.针对该流程,启动一个流程表示发起一个新的出差申请单,这就相当于 java 类与 j ...

  2. Monkey源代码分析之事件注入

    本系列的上一篇文章<Monkey源代码分析之事件源>中我们描写叙述了monkey是怎么从事件源取得命令.然后将命令转换成事件放到事件队列里面的.可是到如今位置我们还没有了解monkey里面 ...

  3. Liferay7 BPM门户开发之47: 集成Activiti待办已办任务清单和流程启动

    首先增加两个Portlet,分别用于待办处理.流程启动.待办是别人发起的流程,流到自己这里的流程:流程启动用于发起新的流程. 程序文件放置于 在ACtivit中待办概念分两种,1是指派给你的,专门的指 ...

  4. activiti 学习( 三 ) 之 流程启动者

    在启动一个流程时,我们会有将当前用户启动的流程保存起来,作为流程发起人(启动人.申请人.提交人) 而在保存这个流程启动者信息,api 没有明确规范该怎么存.所以这里我总结下我学到的保存流程启动者信息的 ...

  5. Monkey源代码分析之执行流程

    在<MonkeyRunner源代码分析之与Android设备通讯方式>中.我们谈及到MonkeyRunner控制目标android设备有多种方法.当中之中的一个就是在目标机器启动一个mon ...

  6. Spark SQL源代码分析之核心流程

    /** Spark SQL源代码分析系列文章*/ 自从去年Spark Submit 2013 Michael Armbrust分享了他的Catalyst,到至今1年多了,Spark SQL的贡献者从几 ...

  7. Activiti源代码分析

    ExecutionEntity内部含有parent,是一个运行树或运行路径.应该是一个流程实例的运行过程,一个实例相应一个ExecutionEntity,通过getActivity得到的是当前正在运行 ...

  8. HBase源代码分析之HRegionServer上MemStore的flush处理流程(一)

    在<HBase源代码分析之HRegion上MemStore的flsuh流程(一)>.<HBase源代码分析之HRegion上MemStore的flsuh流程(二)>等文中.我们 ...

  9. Appium Android Bootstrap源代码分析之启动执行

    通过前面的两篇文章<Appium Android Bootstrap源代码分析之控件AndroidElement>和<Appium Android Bootstrap源代码分析之命令 ...

随机推荐

  1. 深度学习基础系列(一)| 一文看懂用kersa构建模型的各层含义(掌握输出尺寸和可训练参数数量的计算方法)

    我们在学习成熟网络模型时,如VGG.Inception.Resnet等,往往面临的第一个问题便是这些模型的各层参数是如何设置的呢?另外,我们如果要设计自己的网路模型时,又该如何设置各层参数呢?如果模型 ...

  2. 【BZOJ 3106】 3106: [cqoi2013]棋盘游戏 (对抗搜索)

    3106: [cqoi2013]棋盘游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 544  Solved: 233 Description 一个 ...

  3. [POJ1625]Censored!(AC自动机+DP+高精度)

    Censored! Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 10824   Accepted: 2966 Descri ...

  4. HDU 1011 Starship Troopers 树形+背包dp

    http://acm.hdu.edu.cn/showproblem.php?pid=1011   题意:每个节点有两个值bug和brain,当清扫该节点的所有bug时就得到brain值,只有当父节点被 ...

  5. 压测工具Siege

    一.下载 http://www.joedog.org/ http://www.joedog.org/pub/siege/siege-2.70.tar.gz 二.测试 siege -c200 -r10 ...

  6. MongoDB,pymongo

    MongoDB: 数据库,nosql [{ id:1 name:"蔡文姬" age: 16 gender:"女" }, { id:1 name:"蔡文 ...

  7. lightoj 1306 - Solutions to an Equation 扩展的欧几里得

    思路:看题就知道用扩展的欧几里得算法做!!! 首先我们可以求出ax+by=gcd(a,b)=g的一个组解(x0,y0).而要使ax+by=c有解,必须有c%g==0. 继而可以得到ax+by=c的一个 ...

  8. [bzoj1019][SHOI2008]汉诺塔 (动态规划)

    Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操 ...

  9. linux基础命令学习(三)文件搜索 find

    1.使用name选项 查找自己的根目录$Home中的文件,可以用: find ~ -name "*.log" -print  查找当前目录下的文件,可以用: find . -nam ...

  10. 破解MyEclipse2015 stable3.0(亲测可用)

    整个破解过程最好断网: 1.安装好MyEclipse2015 stable3后,打开设置好工作目录后,退出.2.将plugins文件夹中的文件拷贝到myeclipse安装目录的plugins文件夹下, ...