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

时间: 2024-10-29 18:48:35

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

HDFS源码分析DataXceiver之整体流程

        在<HDFS源码分析之DataXceiverServer>一文中,我们了解到在DataNode中,有一个后台工作的线程DataXceiverServer.它被用于接收来自客户端或其他数据节点的数据读写请求,为每个数据读写请求创建一个单独的线程去处理.而处理每次读写请求时所创建的线程,就是本文要讲的DataXceiver.本文,我们来看下DataXceiver的具体实现,着重讲解下它得到数据读写请求后的整体处理流程.         首先,我们先看下DataXceiver的成员变

Linux内核源码分析--内核启动之(6)Image内核启动(do_basic_setup函数)(Linux-3.0 ARMv7)【转】

原文地址:Linux内核源码分析--内核启动之(6)Image内核启动(do_basic_setup函数)(Linux-3.0 ARMv7) 作者:tekkamanninja  转自:http://blog.chinaunix.net/uid-25909619-id-4938396.html     在基本分析完内核启动流程的之后,还有一个比较重要的初始化函数没有分析,那就是do_basic_setup.在内核init线程中调用了do_basic_setup,这个函数也做了很多内核和驱动的初始化

spring启动component-scan类扫描加载过程---源码分析

最近因为写书的事情,一段时间没有写博客了,有朋友最近问到了spring加载类的过程,尤其是基于annotation注解的加载过程,有些时候如果由于某些系统部署的问题,加载不到,很是不解!就针对这个问题,我这篇博客说说spring启动过程,用源码来说明,这部分内容也会在书中出现,只是表达方式会稍微有些区别,我将使用spring 3.0的版本来说明(虽然版本有所区别,但是变化并不是特别大),另外,这里会从WEB中使用spring开始,中途会穿插自己通过new ClassPathXmlApplicat

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

        在<HBase源码分析之HRegion上MemStore的flsuh流程(一)>.<HBase源码分析之HRegion上MemStore的flsuh流程(二)>等文中,我们介绍了HRegion上Memstore flush的主体流程和主要细节.但是,HRegion只是HBase表中按照行的方向对一片连续的数据区域的抽象,它并不能对外提供单独的服务,供客户端或者HBase其它实体调用.而HRegion上MemStore的flush还是要通过HRegionServer来

HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程

        在<HDFS源码分析心跳汇报之数据结构初始化>一文中,我们了解到HDFS心跳相关的BlockPoolManager.BPOfferService.BPServiceActor三者之间的关系,并且知道最终HDFS的心跳是通过BPServiceActor线程实现的.那么,这个BPServiceActor线程到底是如何工作的呢?本文,我们将继续HDFS心跳分析之BPServiceActor工作线程运行流程.         首先,我们先看下         那么,BPServiceA

从源码分析Android的Glide库的图片加载流程及特点_Android

0.基础知识Glide中有一部分单词,我不知道用什么中文可以确切的表达出含义,用英文单词可能在行文中更加合适,还有一些词在Glide中有特别的含义,我理解的可能也不深入,这里先记录一下. (1)View: 一般情况下,指Android中的View及其子类控件(包括自定义的),尤其指ImageView.这些控件可在上面绘制Drawable (2)Target: Glide中重要的概念,目标.它即可以指封装了一个View的Target(ViewTarget),也可以不包含View(SimpleTar

Yarn源码分析之MRAppMaster上MapReduce作业处理总流程(二)

        本文继<Yarn源码分析之MRAppMaster上MapReduce作业处理总流程(一)>,接着讲述MapReduce作业在MRAppMaster上处理总流程,继上篇讲到作业初始化之后的作业启动,关于作业初始化主体流程的详细介绍,请参见<Yarn源码分析之MRAppMaster上MapReduce作业初始化解析>一文.         (三)启动         作业的启动是通过MRAppMaster的startJobs()方法实现的,其代码如下: /** * Th

Yarn源码分析之MRAppMaster上MapReduce作业处理总流程(一)

        我们知道,如果想要在Yarn上运行MapReduce作业,仅需实现一个ApplicationMaster组件即可,而MRAppMaster正是MapReduce在Yarn上ApplicationMaster的实现,由其控制MR作业在Yarn上的执行.如此,随之而来的一个问题就是,MRAppMaster是如何控制MapReduce作业在Yarn上运行的,换句话说,MRAppMaster上MapReduce作业处理总流程是什么?这就是本文要研究的重点.         通过MRApp

HBase源码分析之HRegion上compact流程分析(三)

        在<HBase源码分析之HRegion上compact流程分析(二)>一文中,我们没有讲解真正执行合并的CompactionContext的compact()方法.现在我们来分析下它的具体实现.         首先,CompactionContext表示合并的上下文信息,它只是一个抽象类,其compact()并没有实现,代码如下: /** * Runs the compaction based on current selection. select/forceSelect