Activitiプロセスイベントの概要

境界イベントと中間イベントの違い:境界イベントは関連するノードに関連しています。たとえば、時間制限のある境界イベントがノードに設定されます。このイベントの後、ノードがまだ承認されていない場合は、アクティビティをキャンセルすることを選択できます。 、つまり、次の1つのノードに移動する必要はありません。中間イベントは、ノードの後に​​定義されたイベントです。たとえば、中間定義のイベントは、ノードの後に​​定義されます。ノードが承認されると、タイミング時間を超えた後、次のノードに流れます。要約すると、境界イベントはノード用であり、中間イベントはプロセス用です。

1.ニュースイベント

メッセージイベントは、名前付きメッセージを参照します。各メッセージには名前と内容があります。シグナルとは異なり、メッセージイベントは常に1人の受信者に直接送信されます。
メッセージが新しいプロセスインスタンスの開始をトリガーする必要がある場合は、次のRuntimeServiceメソッドのいずれかを選択して実行します。

//根据消息名称发起流程
ProcessInstance startProcessInstanceByMessage(String messageName);
//传入消息名称和流程变量发起流程
ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);
//传入消息名称,流程变量和业务key发起流程
ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object> processVariables);

これらのメソッドを使用すると、対応するメッセージフローインスタンスを開始できます。
実行中のプロセスインスタンスでメッセージを処理する必要がある場合は、最初にメッセージに基づいて対応するプロセスインスタンスを見つけてから、待機中のプロセスをトリガーします。RuntimeServiceは、メッセージイベントのサブスクリプションに基づいて実行を継続するようにプロセスをトリガーするために、次のメソッドを提供します。

//根据消息名称和流程执行ID触发消息
void messageEventReceived(String messageName, String executionId);
void messageEventReceived(String messageName, String executionId, HashMap<String, Object> processVariables);

#Queryメッセージイベントサブスクリプション

Activitiは、メッセージ開始イベントと中間メッセージイベントをサポートします。
メッセージ開始イベントの場合、メッセージイベントサブスクリプションは特定のプロセス定義に割り当てられます。このニュースサブスクリプションは、ProcessDefinitionQueryを使用して照会できます。

ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
messageEventSubscription("newCallCenterBooking").singleResult();

•メッセージのサブスクリプションポイントに関連付けることができるプロセス定義は一度に1つだけであるため、クエリは常に0または結果を返します。プロセス定義が更新されると、プロセス定義の最新バージョンのみがメッセージイベントにサブスクライブされます。
•メッセージイベントが途中でキャプチャされると、メッセージイベントサブスクリプションが特定の実行に割り当てられます。このニュースイベントのサブスクリプションは、ExecutionQueryを使用して照会できます。

Execution execution = runtimeService.createExecutionQuery()
    .messageEventSubscriptionName("paymentReceived")
    .variableValueEquals("orderId", message.getOrderId()) .singleResult();

•このクエリは、対応するクエリ、通常はプロセス関連の情報を呼び出すことができます(ここでは、最大で1つのプロセスインスタンスがorderIdに対応できます)。
ここに画像の説明を挿入
メッセージ定義はプロセス用であり、ここで定義されたメッセージはノードで選択できます。図に示すように、アプリケーションが送信された後、プロセスは中間メッセージで待機し、メッセージが受信されるまで流れ続けます。
ここに画像の説明を挿入

2.シグナルイベント

シグナルイベントは、名前付きシグナルを参照します。グローバルイベントを通知します(ブロードキャストセマンティクス)。アクティブ化されたすべてのプロセッサに送信されます。
トリガーシグナルイベントは、bpmnノードまたはAPIを介してプロセスインスタンスによってトリガーできます。org.activiti.engine.RuntimeServiceの次のメソッドを使用して、シグナルを手動でトリガーできます。

RuntimeService.signalEventReceived(String signalName);
RuntimeService.signalEventReceived(String signalName, String executionId);                           

signalEventReceived(String signalName);とsignalEventReceived(String signalName、String ExecutionId);の違いは、最初のメソッドはサブスクライブされたすべてのプロセッサにグローバルにシグナルを送信し(ブロードキャストセマンティクス)、2番目のメソッドはプロセスインスタンスを指定するための情報のみを送信することです。
中間キャプチャ信号イベントまたは境界情報イベントによってキャプチャできるキャプチャ信号イベント。

シグナルイベントのサブスクリプションを照会するには、サブスクライブされたすべての特定のシグナルイベントの実行を照会できます。

List<Execution> executions = runtimeService.createExecutionQuery()
    .signalEventSubscriptionName("alert").list();

signalEventReceived(String signalName、String ExecutionId)メソッドを使用して、これらの実行にシグナルを送信できます。

シグナルイベント範囲。デフォルトでは、シグナルはプロセスエンジンのスコープ内でブロードキャストされます。つまり、プロセスインスタンスでシグナルイベントをスローでき、さまざまなプロセスによって定義された他のプロセスインスタンスがこのイベントをリッスンできます。同じプロセスインスタンスでこのシグナルイベントにのみ応答したい場合は、シグナルイベントで定義されたscope属性を使用して、プロセスインスタンスに設定できます。

シグナルを定義するときは、グローバルレベルまたはプロセスインスタンスレベルのいずれかで、イベントのスコープを選択できます
ここに画像の説明を挿入
プロセスインスタンスのシグナルの場合、シグナルはプロセスでスローされる必要があります。つまり、中間シグナルスローイベントが定義されます。
ここに画像の説明を挿入

図に示すように、スーパーバイザーの承認後にシグナルがスローされ、シグナルがキャプチャされた後も実行が続行されます。
ここに画像の説明を挿入

Activitiソースコード分析

for (SignalEventSubscriptionEntity signalEventSubscriptionEntity : signalEvents) {
    
    
      // We only throw the event to globally scoped signals.
      // Process instance scoped signals must be thrown within the process itself
      //这里只实现了全局信号的抛出,流程实例级别的需要流程自己抛出
      if (signalEventSubscriptionEntity.isGlobalScoped()) {
    
    
        
        if (executionId == null && Activiti5Util.isActiviti5ProcessDefinitionId(commandContext, signalEventSubscriptionEntity.getProcessDefinitionId())) {
    
    
          Activiti5CompatibilityHandler activiti5CompatibilityHandler = Activiti5Util.getActiviti5CompatibilityHandler(); 
          activiti5CompatibilityHandler.signalEventReceived(signalEventSubscriptionEntity, payload, async);
          
        } else {
    
    
          Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
              ActivitiEventBuilder.createSignalEvent(ActivitiEventType.ACTIVITY_SIGNALED, signalEventSubscriptionEntity.getActivityId(), eventName, 
                  payload, signalEventSubscriptionEntity.getExecutionId(), signalEventSubscriptionEntity.getProcessInstanceId(), 
                  signalEventSubscriptionEntity.getProcessDefinitionId()));
          
          eventSubscriptionEntityManager.eventReceived(signalEventSubscriptionEntity, payload, async);
        }
      }
    }

プロセスインスタンスレベルでのシグナルの実装は主に

org.activiti.engine.impl.bpmn.helper.SignalThrowingEventListener#onEvent

public void onEvent(ActivitiEvent event) {
    
    
    if (isValidEvent(event)) {
    
    

      if (event.getProcessInstanceId() == null && processInstanceScope) {
    
    
        throw new ActivitiIllegalArgumentException("Cannot throw process-instance scoped signal, since the dispatched event is not part of an ongoing process instance");
      }

      CommandContext commandContext = Context.getCommandContext();
      EventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.getEventSubscriptionEntityManager();
      List<SignalEventSubscriptionEntity> subscriptionEntities = null;
      if (processInstanceScope) {
    
    
        subscriptionEntities = eventSubscriptionEntityManager.findSignalEventSubscriptionsByProcessInstanceAndEventName(event.getProcessInstanceId(), signalName);
      } else {
    
    
        String tenantId = null;
        if (event.getProcessDefinitionId() != null) {
    
    
          ProcessDefinition processDefinition = commandContext.getProcessEngineConfiguration().getDeploymentManager().findDeployedProcessDefinitionById(event.getProcessDefinitionId());
          tenantId = processDefinition.getTenantId();
        }
        subscriptionEntities = eventSubscriptionEntityManager.findSignalEventSubscriptionsByEventName(signalName, tenantId);
      }

      for (SignalEventSubscriptionEntity signalEventSubscriptionEntity : subscriptionEntities) {
    
    
        eventSubscriptionEntityManager.eventReceived(signalEventSubscriptionEntity, null, false);
      }
    }
  }

あなたは見ることができます

3.イベントゲートウェイ

イベントゲートウェイを使用すると、イベントに基づいてフローの方向を決定できます。ゲートウェイの各発信シーケンスフローは、中間キャプチャイベントに接続する必要があります。プロセスがイベントベースのゲートウェイに到達すると、ゲートウェイは待機状態になります。実行は一時停止されます。同時に、発信シーケンスフローごとに相対イベントサブスクリプションが作成されます。
イベントゲートウェイに基づく発信シーケンスフローは、通常のシーケンスフローとは異なることに注意してください。これらのシーケンスフローは実際には「実行」されません。代わりに、イベントゲートウェイに基づいて、プロセスにサブスクライブする必要のあるイベントをプロセスエンジンに決定させます。次の条件を考慮する必要があります。
•イベントベースのゲートウェイには、2つ以上の発信シーケンスフローが必要です。
•イベントゲートウェイに基づいて、intermediateCatchEventタイプのみを使用できます。(Activitiは、イベントベースのゲートウェイの後のReceiveTaskの接続をサポートしていません。)
•イベントベースのゲートウェイに接続されたIntermediateCatchEventは、1つの着信シーケンスフローのみを持つことができます。

図に示すように、このイベントゲートウェイには2つの出口があり、1つは中間タイミングキャプチャイベントにサブスクライブされ、もう1つは中間メッセージキャプチャイベントにサブスクライブされます。設定されたタイミング時間後にメッセージが受信されなくなると、プロセスは終了します。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_34758074/article/details/104644557