activiti 源碼筆記之startProcess


 

rumtimeService.startProcessInstanceByXX方法將啟動流程的任務委派給StartProcessInstanceCmd,此時會根據rumtimeService.startProcessInstanceByXX的XX來用不同的變量構造StartProcessInstanceCmd實例然后執行execute方法,StartProcessInstanceCmd的構造器如下.

(1) processDefinitionKey
         在bpmn20.xml中定義流程元素的id
       < process id = "loanReuqest" name = "Process to handle a loan request">
 
(2)processDefinitionId
        對應流程數據庫中act_re_procdef中的主鍵
(3)businessKey
        關聯的業務主鍵,用於自定義擴展,引擎本身沒有用到.
 
(4)variables
        流程變量
 
execute的執行邏輯如下
(1) 根據processDefinitionKey或proceeDefinitionId在已發布的流程定義中查找,它是先查找緩沖中的流程定義然后再去數據庫中查找以便提高效率,如果找不到或找到的流程定義被掛起將拋出運行時異常ActivitiException.
deploymentCache.findDeployedProcessDefinitionById?Key( processDefinitionId?Key);
(2)創建流程實例
ExecutionEntity processInstance = processDefinition.createProcessInstance(businessKey);
創建流程實例的過程是比較復雜的。
首先流程在創建時必須有一個類型為ActivityImpl的initial變量.
這里為了方便理解暫且可以把ActivityImpl理解為流程中的每個節點元素(除了任務外整個一個流程也可理解為一個節點)的抽象.
它有如下屬性:
public  class ActivityImpl  extends ScopeImpl  implements PvmActivity, HasDIBounds {
 
   private  static  final  long  serialVersionUID = 1L;
   protected List< TransitionImpl> outgoingTransitions =  new ArrayList<TransitionImpl>();
   protected Map<String, TransitionImpl> namedOutgoingTransitions =  new HashMap<String, TransitionImpl>();
   protected List< TransitionImpl> incomingTransitions =  new ArrayList<TransitionImpl>();
   protected ActivityBehavior activityBehavior;
   protected ScopeImpl parent;
   protected  boolean isScope ;
   protected  boolean isAsync ;
   protected  boolean isExclusive ;
 
  // Graphical information
   protected  int x = -1;
   protected  int y = -1;
   protected  int width = -1;
   protected  int height = -1;
 
...........................................
}
比較重要的屬性包括此流程元素的進入、離開路徑和此活動對應的行為(有了這些我們甚至可以在運行時改變流程的運轉和行為),每種不同的流程元素都有不同的行為,actityBehavior實現了當流轉到此節點時對應的處理邏輯.
 
創建流程時initial一般指各種開始事件,我這里單步調試時用了最簡單的StartEvent,下面是它activitiBehavior類,
public  class NoneStartEventActivityBehavior  extends FlowNodeActivityBehavior {
 
  // Nothing to see here.
  // The default behaviour of the BpmnActivity is exactly what
  // a none start event should be doing.
}
它只是為了語義而定義的類,它沒在父類FlowNodeActivityBehavior的基礎上添加任何額外屬性和方法.FlowNodeActivityBehavior是所有bpmn元素的超類,FlowNodeActivityBehavior的默認只是離開此節點,而不做任何額外處理.
ProcessDefinitionImpl的newProcessInstance是真正創建流程實例的地方,它使用下面這個以activityImpl為參數的構造器創建ExecutionEntity對象.這里和ProcessInstance的繼承關系可以看到一個流程實例實際上也是一個執行實例,從邏輯上理解一個流程實例也就是一個可執行的路徑.當然反過來說就不對了,執行實例不僅僅單指流程實例.
public ExecutionEntity(ActivityImpl activityImpl) {
     this. startingExecution =  new StartingExecution(activityImpl);
}
在創建流程后會在流程數據庫中插入一條ExecutionEntity數據,在act_ru_execution表中可以看到這個execution的id和proc_inst_id的值是一樣的
 
在完成流程實基本例化后,對此流程實例的變量再進行一些初始化
   processInstance.setProcessDefinition(  this);
  processInstance.setProcessInstance(processInstance);
  processInstance.initialize();
前兩行代碼的操作很簡單,第三行的initialize方法又是有些復雜的.它負責設置流程的變量、任務、調度任務、訂閱事件等,它這涉及到流程引擎的范圍體系,需要另開文章好好分析.
(3)啟動流程
processInstance.start();
 
public  void start() {
     if( startingExecution ==  null && isProcessInstanceType()) {
      startingExecution =  new StartingExecution(processDefinition .getInitial());
    }
    performOperation (AtomicOperation.  PROCESS_START);
}
在activiti里一個動作都將對應一種行為,啟動流程的動作將執行PROCESS_START的原子操作
   if(executionOperation.isAsync(  this )) {
      scheduleAtomicOperationAsync(executionOperation);
    }  else {
      performOperationSync(executionOperation);
    }   
如果是異步的就在調度線程池中拿到線程執行,否則就在當前線程內執行
 
以下是activiti原子操作的類型
 
 
 
AtomicOperationProcessStart做的事情不多,它只是觸發了所有它范圍內綁定的所有監聽,這也是所有原子操作的基本默認行為

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM