Resumen de eventos del proceso Activiti

La diferencia entre eventos de límite y eventos intermedios: los eventos de límite están relacionados con nodos asociados. Por ejemplo, un evento de límite cronometrado se establece en un nodo. Después de este evento, si el nodo aún no ha sido aprobado, puede optar por cancelar la actividad , lo que significa que no es necesario pasar al siguiente nodo One. Un evento intermedio es un evento definido después de un nodo. Por ejemplo, un evento definido intermedio se define después de un nodo. Una vez aprobado el nodo, pasará al siguiente nodo después de que se exceda el tiempo de temporización. En resumen, los eventos de límite son para nodos y los eventos intermedios son para procesos.

1. Evento de noticias

El evento de mensaje hará referencia a un mensaje con nombre. Cada mensaje tiene un nombre y un contenido. A diferencia de las señales, los eventos de mensajes siempre se envían directamente a un destinatario.
Si el mensaje debe desencadenar el inicio de una nueva instancia de proceso, elija uno de los siguientes métodos de RuntimeService para ejecutar:

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

Estos métodos permiten iniciar la instancia de flujo de mensajes correspondiente.
Si el mensaje necesita ser procesado por la instancia del proceso en ejecución, primero busque la instancia del proceso correspondiente según el mensaje y luego active el proceso en espera. RuntimeService proporciona los siguientes métodos para activar el proceso para continuar con la ejecución en función de la suscripción de eventos de mensajes:

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

Suscripción a evento de #Query message

Activiti admite eventos de inicio de mensajes y eventos de mensajes intermedios.
En el caso de un evento de inicio de mensaje, la suscripción al evento de mensaje se asigna a una definición de proceso específica. Esta suscripción de noticias se puede consultar utilizando ProcessDefinitionQuery:

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

• Debido a que solo puede haber una definición de proceso asociada con el punto de suscripción del mensaje a la vez, la consulta siempre devuelve 0 o un resultado. Si se actualiza la definición de proceso, solo la última versión de la definición de proceso se suscribirá al evento de mensaje.
• Cuando se captura un evento de mensaje en el medio, la suscripción del evento de mensaje se asignará a una ejecución específica. Esta suscripción a eventos de noticias se puede consultar mediante ExecutionQuery:

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

• Esta consulta puede llamar a la consulta correspondiente, normalmente información relacionada con el proceso (aquí, como máximo una instancia de proceso puede corresponder a orderId).
Inserte la descripción de la imagen aquí
La definición del mensaje es para el proceso y el mensaje definido aquí se puede seleccionar en el nodo. Como se muestra en la figura, después de que se envía la solicitud, el proceso espera en el mensaje intermedio y continuará fluyendo hasta que se reciba el mensaje.
Inserte la descripción de la imagen aquí

2. Evento de señal

El evento de señal hace referencia a una señal con nombre. Señalar eventos globales (semántica de transmisión). Se enviará a todos los procesadores activados.
El evento de señal de disparo puede ser disparado por una instancia de proceso a través del nodo bpmn o mediante API. Los siguientes métodos en org.activiti.engine.RuntimeService se pueden utilizar para activar manualmente una señal.

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

La diferencia entre signalEventReceived (String signalName); y signalEventReceived (String signalName, String executionId); es que el primer método envía la señal a todos los procesadores suscritos globalmente (semántica de difusión), y el segundo método solo envía información para especificar la instancia del proceso.
Capturar eventos de señales, que pueden ser capturados por eventos de señales de captura intermedias o eventos de información de límites.

Para consultar la suscripción de eventos de señal, puede consultar la ejecución de todos los eventos de señal específicos suscritos:

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

Podemos usar el método signalEventReceived (String signalName, String executionId) para enviar señales a estas ejecuciones.

Rango de eventos de señal. De forma predeterminada, la señal se transmitirá dentro del alcance del motor de proceso. En otras palabras, puede lanzar un evento de señal en una instancia de proceso, y otras instancias de proceso definidas por diferentes procesos pueden escuchar este evento. A veces, solo desea responder a este evento de señal en la misma instancia de proceso, puede usar el atributo de alcance definido por el evento de señal para establecerlo en la instancia de proceso.

Al definir una señal, puede elegir el alcance del evento, ya sea a nivel global o de instancia de proceso .
Inserte la descripción de la imagen aquí
Para la señal de la instancia de proceso , la señal debe lanzarse en el proceso, es decir, se define el evento de lanzamiento de señal intermedio.
Inserte la descripción de la imagen aquí

Como se muestra en la figura, se lanzará una señal después de la aprobación del supervisor y la ejecución continuará después de que se capture la señal.
Inserte la descripción de la imagen aquí

Análisis del código fuente de 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);
        }
      }
    }

La implementación de la señal a nivel de instancia de proceso es principalmente

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);
      }
    }
  }

Puedes echar un vistazo

3. Pasarela de eventos

La puerta de enlace de eventos permite determinar la dirección del flujo en función del evento. Cada flujo de secuencia saliente de la puerta de enlace debe estar conectado a un evento de captura intermedio. Cuando el proceso llega a una puerta de enlace basada en eventos, la puerta de enlace entrará en un estado de espera: se suspenderá la ejecución. Al mismo tiempo, se crea una suscripción de evento relativo para cada flujo de secuencia saliente.
Tenga en cuenta que el flujo de secuencia saliente basado en la puerta de enlace de eventos es diferente del flujo de secuencia normal. Estos flujos de secuencia no se "ejecutarán" realmente. En su lugar, permiten que el motor de procesos decida a qué eventos deben suscribirse al proceso en función de la puerta de enlace de eventos. Deben tenerse en cuenta las siguientes condiciones:
• La puerta de enlace basada en eventos debe tener dos o más flujos de secuencia salientes.
• Según la puerta de enlace de eventos, solo se puede utilizar el tipo de evento de captura intermedio. (Activiti no admite la conexión de ReceiveTask después de la puerta de enlace basada en eventos).
• IntermediateCatchEvent conectado a la puerta de enlace basada en eventos solo puede tener un flujo de secuencia entrante.

Como se muestra en la figura, esta pasarela de eventos tiene dos salidas, una está suscrita a un evento de captura de tiempo intermedio y la otra está suscrita a un evento de captura de mensaje intermedio. El proceso finalizará cuando no se reciba ningún mensaje después del tiempo establecido.
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_34758074/article/details/104644557
Recomendado
Clasificación