org.activiti.engine

news2025/7/12 7:37:10

org.activiti.engine

  • 目录
    • 概述
      • 需求:
    • 设计思路
    • 实现思路分析
      • 1.TaskService
      • 2.RuntimeService
      • 3.ProcessEngines
      • 4.ProcessEngineLifecycleListener
      • 5.ProcessEngines
  • 参考资料和推荐阅读

Survive by day and develop by night.
talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge Survive.
happy for hardess to solve denpendies.

目录

在这里插入图片描述

概述

org.activiti.engine是一个非常常见的需求。

需求:

设计思路

实现思路分析

1.TaskService

public interface TaskService {

  /**
   * Creates a new task that is not related to any process instance.
   *
   * The returned task is transient and must be saved with {@link #saveTask(Task)} 'manually'.
   */
  Task newTask();

  /** create a new task with a user defined task id */
  Task newTask(String taskId);

  /**
   * Saves the given task to the persistent data store. If the task is already present in the persistent store, it is updated. After a new task has been saved, the task instance passed into this
   * method is updated with the id of the newly created task.
   *
   * @param task
   *          the task, cannot be null.
   */
  Task saveTask(Task task);

  /**
   * Deletes the given task, not deleting historic information that is related to this task.
   *
   * @param taskId
   *          The id of the task that will be deleted, cannot be null. If no task exists with the given taskId, the operation is ignored.
   * @throws ActivitiObjectNotFoundException
   *           when the task with given id does not exist.
   * @throws ActivitiException
   *           when an error occurs while deleting the task or in case the task is part of a running process.
   */
  void deleteTask(String taskId);

  /**
   * Deletes all tasks of the given collection, not deleting historic information that is related to these tasks.
   *
   * @param taskIds
   *          The id's of the tasks that will be deleted, cannot be null. All id's in the list that don't have an existing task will be ignored.
   * @throws ActivitiObjectNotFoundException
   *           when one of the task does not exist.
   * @throws ActivitiException
   *           when an error occurs while deleting the tasks or in case one of the tasks is part of a running process.
   */
  void deleteTasks(Collection<String> taskIds);

  /**
   * Deletes the given task.
   *
   * @param taskId
   *          The id of the task that will be deleted, cannot be null. If no task exists with the given taskId, the operation is ignored.
   * @param cascade
   *          If cascade is true, also the historic information related to this task is deleted.
   * @throws ActivitiObjectNotFoundException
   *           when the task with given id does not exist.
   * @throws ActivitiException
   *           when an error occurs while deleting the task or in case the task is part of a running process.
   */
  void deleteTask(String taskId, boolean cascade);

  /**
   * Deletes all tasks of the given collection.
   *
   * @param taskIds
   *          The id's of the tasks that will be deleted, cannot be null. All id's in the list that don't have an existing task will be ignored.
   * @param cascade
   *          If cascade is true, also the historic information related to this task is deleted.
   * @throws ActivitiObjectNotFoundException
   *           when one of the tasks does not exist.
   * @throws ActivitiException
   *           when an error occurs while deleting the tasks or in case one of the tasks is part of a running process.
   */
  void deleteTasks(Collection<String> taskIds, boolean cascade);

  /**
   * Deletes the given task, not deleting historic information that is related to this task..
   *
   * @param taskId
   *          The id of the task that will be deleted, cannot be null. If no task exists with the given taskId, the operation is ignored.
   * @param deleteReason
   *          reason the task is deleted. Is recorded in history, if enabled.
   * @throws ActivitiObjectNotFoundException
   *           when the task with given id does not exist.
   * @throws ActivitiException
   *           when an error occurs while deleting the task or in case the task is part of a running process
   */
  void deleteTask(String taskId, String deleteReason);

  /**
   * Deletes the given task, not deleting historic information that is related to this task..
   *
   * @param taskId
   *          The id of the task that will be deleted, cannot be null. If no task exists with the given taskId, the operation is ignored.
   * @param deleteReason
   *          reason the task is deleted. Is recorded in history, if enabled.
   * @param cancel
   *          mark the task as cancelled
   * @throws ActivitiObjectNotFoundException
   *           when the task with given id does not exist.
   * @throws ActivitiException
   *           when an error occurs while deleting the task or in case the task is part of a running process
   */
  void deleteTask(String taskId, String deleteReason, boolean cancel);

  /**
   * Deletes all tasks of the given collection, not deleting historic information that is related to these tasks.
   *
   * @param taskIds
   *          The id's of the tasks that will be deleted, cannot be null. All id's in the list that don't have an existing task will be ignored.
   * @param deleteReason
   *          reason the task is deleted. Is recorded in history, if enabled.
   * @throws ActivitiObjectNotFoundException
   *           when one of the tasks does not exist.
   * @throws ActivitiException
   *           when an error occurs while deleting the tasks or in case one of the tasks is part of a running process.
   */
  void deleteTasks(Collection<String> taskIds, String deleteReason);

  /**
   * Deletes all tasks of the given collection, not deleting historic information that is related to these tasks.
   *
   * @param taskIds
   *          The id's of the tasks that will be deleted, cannot be null. All id's in the list that don't have an existing task will be ignored.
   * @param deleteReason
   *          reason the task is deleted. Is recorded in history, if enabled.
   * @oaramn cancel
   *           mark the task as cancelled
   * @throws ActivitiObjectNotFoundException
   *           when one of the tasks does not exist.
   * @throws ActivitiException
   *           when an error occurs while deleting the tasks or in case one of the tasks is part of a running process.
   */
  void deleteTasks(Collection<String> taskIds, String deleteReason, boolean cancel);

  /**
   * Claim responsibility for a task: the given user is made assignee for the task. The difference with {@link #setAssignee(String, String)} is that here a check is done if the task already has a user
   * assigned to it. No check is done whether the user is known by the identity component.
   *
   * @param taskId
   *          task to claim, cannot be null.
   * @param userId
   *          user that claims the task. When userId is null the task is unclaimed, assigned to no one.
   * @throws ActivitiObjectNotFoundException
   *           when the task doesn't exist.
   * @throws ActivitiTaskAlreadyClaimedException
   *           when the task is already claimed by another user.
   */
  void claim(String taskId, String userId);

  /**
   * A shortcut to {@link #claim} with null user in order to unclaim the task
   *
   * @param taskId
   *          task to unclaim, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when the task doesn't exist.
   */
  void unclaim(String taskId);

  /**
   * Called when the task is successfully executed.
   *
   * @param taskId
   *          the id of the task to complete, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when no task exists with the given id.
   * @throws ActivitiException
   *           when this task is {@link DelegationState#PENDING} delegation.
   */
  void complete(String taskId);

  /**
   * Delegates the task to another user. This means that the assignee is set and the delegation state is set to {@link DelegationState#PENDING}. If no owner is set on the task, the owner is set to the
   * current assignee of the task.
   *
   * @param taskId
   *          The id of the task that will be delegated.
   * @param userId
   *          The id of the user that will be set as assignee.
   * @throws ActivitiObjectNotF

2.RuntimeService

public interface RuntimeService {

  /**
   * Create a {@link ProcessInstanceBuilder}, that allows to set various options for starting a process instance,
   * as an alternative to the various startProcessInstanceByXX methods.
   */
  ProcessInstanceBuilder createProcessInstanceBuilder();

  /**
   * Starts a process instance previously created.
   *
   * @param createdProcessInstance
   *          The already created process instance.
   * @throws ActivitiObjectNotFoundException
   *          when user does not have permission to start the process instance
   * @throws NotFoundException
   *          when no process instance with the given id is found
   */
  ProcessInstance startCreatedProcessInstance(ProcessInstance createdProcessInstance, Map<String, Object> variables);

  /**
   * Starts a new process instance in the latest version of the process definition with the given key.
   *
   * @param processDefinitionKey
   *          key of process definition, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when no process definition is deployed with the given key.
   */
  ProcessInstance startProcessInstanceByKey(String processDefinitionKey);

  /**
   * Starts a new process instance in the latest version of the process definition with the given key.
   *
   * A business key can be provided to associate the process instance with a certain identifier that has a clear business meaning. For example in an order process, the business key could be an order
   * id. This business key can then be used to easily look up that process instance , see {@link ProcessInstanceQuery#processInstanceBusinessKey(String)}. Providing such a business key is definitely a
   * best practice.
   *
   * @param processDefinitionKey
   *          key of process definition, cannot be null.
   * @param businessKey
   *          a key that uniquely identifies the process instance in the context or the given process definition.
   * @throws ActivitiObjectNotFoundException
   *           when no process definition is deployed with the given key.
   */
  ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey);

  /**
   * Starts a new process instance in the latest version of the process definition with the given key
   *
   * @param processDefinitionKey
   *          key of process definition, cannot be null.
   * @param variables
   *          the variables to pass, can be null.
   * @throws ActivitiObjectNotFoundException
   *           when no process definition is deployed with the given key.
   */
  ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables);

  /**
   * Starts a new process instance in the latest version of the process definition with the given key.
   *
   * A business key can be provided to associate the process instance with a certain identifier that has a clear business meaning. For example in an order process, the business key could be an order
   * id. This business key can then be used to easily look up that process instance , see {@link ProcessInstanceQuery#processInstanceBusinessKey(String)}. Providing such a business key is definitely a
   * best practice.
   *
   * The combination of processdefinitionKey-businessKey must be unique.
   *
   * @param processDefinitionKey
   *          key of process definition, cannot be null.
   * @param variables
   *          the variables to pass, can be null.
   * @param businessKey
   *          a key that uniquely identifies the process instance in the context or the given process definition.
   * @throws ActivitiObjectNotFoundException
   *           when no process definition is deployed with the given key.
   */
  ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables);

  /**
   * Similar to {@link #startProcessInstanceByKey(String)}, but using a specific tenant identifier.
   */
  ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String tenantId);

  /**
   * Similar to {@link #startProcessInstanceByKey(String, String)}, but using a specific tenant identifier.
   */
  ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String businessKey, String tenantId);

  /**
   * Similar to {@link #startProcessInstanceByKey(String, Map)}, but using a specific tenant identifier.
   */
  ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, Map<String, Object> variables, String tenantId);

  /**
   * Similar to {@link #startProcessInstanceByKey(String, String, Map)}, but using a specific tenant identifier.
   */
  ProcessInstance startProcessInstanceByKeyAndTenantId(String processDefinitionKey, String businessKey, Map<String, Object> variables, String tenantId);

  /**
   * Starts a new process instance in the exactly specified version of the process definition with the given id.
   *
   * @param processDefinitionId
   *          the id of the process definition, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when no process definition is deployed with the given key.
   */
  ProcessInstance startProcessInstanceById(String processDefinitionId);

  /**
   * Starts a new process instance in the exactly specified version of the process definition with the given id.
   *
   * A business key can be provided to associate the process instance with a certain identifier that has a clear business meaning. For example in an order process, the business key could be an order
   * id. This business key can then be used to easily look up that process instance , see {@link ProcessInstanceQuery#processInstanceBusinessKey(String)}. Providing such a business key is definitely a
   * best practice.
   *
   * @param processDefinitionId
   *          the id of the process definition, cannot be null.
   * @param businessKey
   *          a key that uniquely identifies the process instance in the context or the given process definition.
   * @throws ActivitiObjectNotFoundException
   *           when no process definition is deployed with the given key.
   */
  ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey);

  /**
   * Starts a new process instance in the exactly specified version of the process definition with the given id.
   *
   * @param processDefinitionId
   *          the id of the process definition, cannot be null.
   * @param variables
   *          variables to be passed, can be null
   * @throws ActivitiObjectNotFoundException
   *           when no process definition is deployed with the given key.
   */
  ProcessInstance startProcessInstanceById(String processDefinitionId, Map<String, Object> variables);

  /**
   * Starts a new process instance in the exactly specified version of the process definition with the given id.
   *
   * A business key can be provided to associate the process instance with a certain identifier that has a clear business meaning. For example in an order process, the business key could be an order
   * id. This business key can then be used to easily look up that process instance , see {@link ProcessInstanceQuery#processInstanceBusinessKey(String)}. Providing such a business key is definitely a
   * best practice.
   *
   * @param processDefinitionId
   *          the id of the process definition, cannot be null.
   * @param variables
   *          variables to be passed, can be null
   * @throws ActivitiObjectNotFoundException
   *           when no process definition is deployed with the given key.
   */
  ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables);

  /**
   * <p>
   * Signals the process engine that a message is received and starts a new {@link ProcessInstance}.
   * </p>
   *
   * <p>
   * Calling this method can have two different outcomes:
   * <ul>
   * <li>If the message name is associated with a message start event, a new process instance is started.</li>
   * <li>If no subscription to a message with the given name exists, {@link ActivitiException} is thrown</li>
   * </ul>
   * </p>
   *
   * @param messageName
   *          the 'name' of the message as specified as an attribute on the bpmn20 {@code <message name="messageName" />} element.
   *
   * @return the {@link ProcessInstance} object representing the started process instance
   *
   * @throws ActivitiException
   *           if no subscription to a message with the given name exists
   *
   * @since 5.9
   */
  ProcessInstance startProcessInstanceByMessage(String messageName);

  /**
   * Similar to {@link RuntimeService#startProcessInstanceByMessage(String)}, but with tenant context.
   */
  ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String tenantId);

  /**
   * <p>
   * Signals the process engine that a message is received and starts a new {@link ProcessInstance}.
   * </p>
   *
   * See {@link #startProcessInstanceByMessage(String, Map)}. This method allows specifying a business key.
   *
   * @param messageName
   *          the 'name' of the message as specified as an attribute on the bpmn20 {@code <message name="messageName" />} element.
   * @param businessKey
   *          the business key which is added to the started process instance
   *
   * @throws ActivitiException
   *           if no subscription to a message with the given name exists
   *
   * @since 5.10
   */
  ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey);

  /**
   * Similar to {@link RuntimeService#startProcessInstanceByMessage(String, String)}, but with tenant context.
   */
  ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String businessKey, String tenantId);

  /**
   * <p>
   * Signals the process engine that a message is received and starts a new {@link ProcessInstance}.
   * </p>
   *
   * See {@link #startProcessInstanceByMessage(String)}. In addition, this method allows specifying a the payload of the message as a map of process variables.
   *
   * @param messageName
   *          the 'name' of the message as specified as an attribute on the bpmn20 {@code <message name="messageName" />} element.
   * @param processVariables
   *          the 'payload' of the message. The variables are added as processes variables to the started process instance.
   * @return the {@link ProcessInstance} object representing the started process instance
   *
   * @throws ActivitiException
   *           if no subscription to a message with the given name exists
   *
   * @since 5.9
   */
  ProcessInstance startProcessInstanceByMessage(String messageName, Map<String, Object> processVariables);

  /**
   * Similar to {@link RuntimeService#startProcessInstanceByMessage(String, Map<String, Object>)}, but with tenant context.
   */
  ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, Map<String, Object> processVariables, String tenantId);

  /**
   * <p>
   * Signals the process engine that a message is received and starts a new {@link ProcessInstance}.
   * </p>
   *
   * See {@link #startProcessInstanceByMessage(String, Map)}. In addition, this method allows specifying a business key.
   *
   * @param messageName
   *          the 'name' of the message as specified as an attribute on the bpmn20 {@code <message name="messageName" />} element.
   * @param businessKey
   *          the business key which is added to the started process instance
   * @param processVariables
   *          the 'payload' of the message. The variables are added as processes variables to the started process instance.
   * @return the {@link ProcessInstance} object representing the started process instance
   *
   * @throws ActivitiException
   *           if no subscription to a message with the given name exists
   *
   * @since 5.9
   */
  ProcessInstance startProcessInstanceByMessage(String messageName, String businessKey, Map<String, Object> processVariables);

  /**
   * Similar to {@link RuntimeService#startProcessInstanceByMessage(String, String, Map<String, Object>)}, but with tenant context.
   */
  ProcessInstance startProcessInstanceByMessageAndTenantId(String messageName, String businessKey, Map<String, Object> processVariables, String tenantId);

  /**
   * Delete an existing runtime process instance.
   *
   * @param processInstanceId
   *          id of process instance to delete, cannot be null.
   * @param deleteReason
   *          reason for deleting, can be null.
   * @throws ActivitiObjectNotFoundException
   *           when no process instance is found with the given id.
   */
  void deleteProcessInstance(String processInstanceId, String deleteReason);

  /**
   * Finds the activity ids for all executions that are waiting in activities. This is a list because a single activity can be active multiple times.
   *
   * @param executionId
   *          id of the execution, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when no execution exists with the given executionId.
   */
  List<String> getActiveActivityIds(String executionId);

  /**
   * Sends an external trigger to an activity instance that is waiting inside the given execution.
   *
   * @param executionId
   *          id of execution to signal, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when no execution is found for the given executionId.
   */
  void trigger(String executionId);

  /**
   * Sends an external trigger to an activity instance that is waiting inside the given execution.
   *
   * @param executionId
   *          id of execution to signal, cannot be null.
   * @param processVariables
   *          a map of process variables
   * @throws ActivitiObjectNotFoundException
   *           when no execution is found for the given executionId.
   */
  void trigger(String executionId, Map<String, Object> processVariables);


  /**
   * Similar to {@link #trigger(String, Map)}, but with an extra parameter that allows to pass
   * transient variables.
   */
  void trigger(String executionId, Map<String, Object> processVariables, Map<String, Object> transientVariables);

  /**
   * Updates the business key for the provided process instance
   *
   * @param processInstanceId
   *          id of the process instance to set the business key, cannot be null
   * @param businessKey
   *          new businessKey value
   */
  void updateBusinessKey(String processInstanceId, String businessKey);

  // Identity Links
  // ///

  /**
   * Involves a user with a process instance. The type of identity link is defined by the given identityLinkType.
   *
   * @param processInstanceId
   *          id of the process instance, cannot be null.
   * @param userId
   *          id of the user involve, cannot be null.
   * @param identityLinkType
   *          type of identityLink, cannot be null (@see {@link IdentityLinkType}).
   * @throws ActivitiObjectNotFoundException
   *           when the process instance doesn't exist.
   */
  void addUserIdentityLink(String processInstanceId, String userId, String identityLinkType);

  /**
   * Involves a group with a process instance. The type of identityLink is defined by the given identityLink.
   *
   * @param processInstanceId
   *          id of the process instance, cannot be null.
   * @param groupId
   *          id of the group to involve, cannot be null.
   * @param identityLinkType
   *          type of identity, cannot be null (@see {@link IdentityLinkType}).
   * @throws ActivitiObjectNotFoundException
   *           when the process instance or group doesn't exist.
   */
  void addGroupIdentityLink(String processInstanceId, String groupId, String identityLinkType);

  /**
   * Convenience shorthand for {@link #addUserIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
   *
   * @param processInstanceId
   *          id of the process instance, cannot be null.
   * @param userId
   *          id of the user to use as candidate, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when the task or user doesn't exist.
   */
  void addParticipantUser(String processInstanceId, String userId);

  /**
   * Convenience shorthand for {@link #addGroupIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
   *
   * @param processInstanceId
   *          id of the process instance, cannot be null.
   * @param groupId
   *          id of the group to use as candidate, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when the task or group doesn't exist.
   */
  void addParticipantGroup(String processInstanceId, String groupId);

  /**
   * Convenience shorthand for {@link #deleteUserIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
   *
   * @param processInstanceId
   *          id of the process instance, cannot be null.
   * @param userId
   *          id of the user to use as candidate, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when the task or user doesn't exist.
   */
  void deleteParticipantUser(String processInstanceId, String userId);

  /**
   * Convenience shorthand for {@link #deleteGroupIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
   *
   * @param processInstanceId
   *          id of the process instance, cannot be null.
   * @param groupId
   *          id of the group to use as candidate, cannot be null.
   * @throws ActivitiObjectNotFoundException
   *           when the task or group doesn't exist.
   */
  void deleteParticipantGroup(String processInstanceId, String groupId);

  /**
   * Removes the association between a user and a process instance for the given identityLinkType.
   *
   * @param processInstanceId
   *          id of the process instance, cannot be null.
   * @param userId
   *          id of the user involve, cannot be null.
   * @param identityLinkType
   *          type of identityLink, cannot be null (@see {@link IdentityLinkType}).
   * @throws ActivitiObjectNotFoundException
   *           when the task or user doesn't exist.
   */
  void deleteUserIdentityLink(String processInstanceId, String userId, String identityLinkType);

  /**
   * Removes the association between a group and a process instance for the given identityLinkType.
   *
   * @param processInstanceId
   *          id of the process instance, cannot be null.
   * @param groupId
   *          id of the group to involve, cannot be null.
   * @param identityLinkType
   *          type of identity, cannot be null (@see {@link IdentityLinkType}).
   * @throws ActivitiObjectNotFoundException
   *           when the task or group doesn't exist.
   */
  void deleteGroupIdentityLink(String processInstanceId, String groupId, String identityLinkType);

  /**
   * Retrieves the {@link IdentityLink}s associated with the given process instance. Such an {@link IdentityLink} informs how a certain user is involved with a process instance.
   */
  List<IdentityLink> getIdentityLinksForProcessInstance(String instanceId);

  // Variables
  // 

在这里插入图片描述

3.ProcessEngines

在这里插入图片描述

public abstract class ProcessEngines {

  private static Logger log = LoggerFactory.getLogger(ProcessEngines.class);

  public static final String NAME_DEFAULT = "default";

  protected static boolean isInitialized;
  protected static Map<String, ProcessEngine> processEngines = new HashMap<String, ProcessEngine>();
  protected static Map<String, ProcessEngineInfo> processEngineInfosByName = new HashMap<String, ProcessEngineInfo>();
  protected static Map<String, ProcessEngineInfo> processEngineInfosByResourceUrl = new HashMap<String, ProcessEngineInfo>();
  protected static List<ProcessEngineInfo> processEngineInfos = new ArrayList<ProcessEngineInfo>();

  /**
   * Initializes all process engines that can be found on the classpath for resources <code>activiti.cfg.xml</code> (plain Activiti style configuration) and for resources
   * <code>activiti-context.xml</code> (Spring style configuration).
   */
  public synchronized static void init() {
    if (!isInitialized()) {
      if (processEngines == null) {
        // Create new map to store process-engines if current map is
        // null
        processEngines = new HashMap<String, ProcessEngine>();
      }
      ClassLoader classLoader = ReflectUtil.getClassLoader();
      Enumeration<URL> resources = null;
      try {
        resources = classLoader.getResources("activiti.cfg.xml");
      } catch (IOException e) {
        throw new ActivitiIllegalArgumentException("problem retrieving activiti.cfg.xml resources on the classpath: " + System.getProperty("java.class.path"), e);
      }

      // Remove duplicated configuration URL's using set. Some
      // classloaders may return identical URL's twice, causing duplicate
      // startups
      Set<URL> configUrls = new HashSet<URL>();
      while (resources.hasMoreElements()) {
        configUrls.add(resources.nextElement());
      }
      for (Iterator<URL> iterator = configUrls.iterator(); iterator.hasNext();) {
        URL resource = iterator.next();
        log.info("Initializing process engine using configuration '{}'", resource.toString());
        initProcessEngineFromResource(resource);
      }

      try {
        resources = classLoader.getResources("activiti-context.xml");
      } catch (IOException e) {
        throw new ActivitiIllegalArgumentException("problem retrieving activiti-context.xml resources on the classpath: " + System.getProperty("java.class.path"), e);
      }
      while (resources.hasMoreElements()) {
        URL resource = resources.nextElement();
        log.info("Initializing process engine using Spring configuration '{}'", resource.toString());
        initProcessEngineFromSpringResource(resource);
      }

      setInitialized(true);
    } else {
      log.info("Process engines already initialized");
    }
  }

  protected static void initProcessEngineFromSpringResource(URL resource) {
    try {
      Class<?> springConfigurationHelperClass = ReflectUtil.loadClass("org.activiti.spring.SpringConfigurationHelper");
      Method method = springConfigurationHelperClass.getDeclaredMethod("buildProcessEngine", new Class<?>[] { URL.class });
      ProcessEngine processEngine = (ProcessEngine) method.invoke(null, new Object[] { resource });

      String processEngineName = processEngine.getName();
      ProcessEngineInfo processEngineInfo = new ProcessEngineInfoImpl(processEngineName, resource.toString(), null);
      processEngineInfosByName.put(processEngineName, processEngineInfo);
      processEngineInfosByResourceUrl.put(resource.toString(), processEngineInfo);

    } catch (Exception e) {
      throw new ActivitiException("couldn't initialize process engine from spring configuration resource " + resource.toString() + ": " + e.getMessage(), e);
    }
  }

  /**
   * Registers the given process engine. No {@link ProcessEngineInfo} will be available for this process engine. An engine that is registered will be closed when the {@link ProcessEngines#destroy()}
   * is called.
   */
  public static void registerProcessEngine(ProcessEngine processEngine) {
    processEngines.put(processEngine.getName(), processEngine);
  }

  /**
   * Unregisters the given process engine.
   */
  public static void unregister(ProcessEngine processEngine) {
    processEngines.remove(processEngine.getName());
  }

  private static ProcessEngineInfo initProcessEngineFromResource(URL resourceUrl) {
    ProcessEngineInfo processEngineInfo = processEngineInfosByResourceUrl.get(resourceUrl.toString());
    // if there is an existing process engine info
    if (processEngineInfo != null) {
      // remove that process engine from the member fields
      processEngineInfos.remove(processEngineInfo);
      if (processEngineInfo.getException() == null) {
        String processEngineName = processEngineInfo.getName();
        processEngines.remove(processEngineName);
        processEngineInfosByName.remove(processEngineName);
      }
      processEngineInfosByResourceUrl.remove(processEngineInfo.getResourceUrl());
    }

    String resourceUrlString = resourceUrl.toString();
    try {
      log.info("initializing process engine for resource {}", resourceUrl);
      ProcessEngine processEngine = buildProcessEngine(resourceUrl);
      String processEngineName = processEngine.getName();
      log.info("initialised process engine {}", processEngineName);
      processEngineInfo = new ProcessEngineInfoImpl(processEngineName, resourceUrlString, null);
      processEngines.put(processEngineName, processEngine);
      processEngineInfosByName.put(processEngineName, processEngineInfo);
    } catch (Throwable e) {
      log.error("Exception while initializing process engine: {}", e.getMessage(), e);
      processEngineInfo = new ProcessEngineInfoImpl(null, resourceUrlString, getExceptionString(e));
    }
    processEngineInfosByResourceUrl.put(resourceUrlString, processEngineInfo);
    processEngineInfos.add(processEngineInfo);
    return processEngineInfo;
  }

  private static String getExceptionString(Throwable e) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    return sw.toString();
  }

  private static ProcessEngine buildProcessEngine(URL resource) {
    InputStream inputStream = null;
    try {
      inputStream = resource.openStream();
      ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream);
      return processEngineConfiguration.buildProcessEngine();

    } catch (IOException e) {
      throw new ActivitiIllegalArgumentException("couldn't open resource stream: " + e.getMessage(), e);
    } finally {
      IoUtil.closeSilently(inputStream);
    }
  }

  /** Get initialization results. */
  public static List<ProcessEngineInfo> getProcessEngineInfos() {
    return processEngineInfos;
  }

  /**
   * Get initialization results. Only info will we available for process engines which were added in the {@link ProcessEngines#init()}. No {@link ProcessEngineInfo} is available for engines which were
   * registered programatically.
   */
  public static ProcessEngineInfo getProcessEngineInfo(String processEngineName) {
    return processEngineInfosByName.get(processEngineName);
  }

  public static ProcessEngine getDefaultProcessEngine() {
    return getProcessEngine(NAME_DEFAULT);
  }

  /**
   * obtain a process engine by name.
   *
   * @param processEngineName
   *          is the name of the process engine or null for the default process engine.
   */
  public static ProcessEngine getProcessEngine(String processEngineName) {
    if (!isInitialized()) {
      init();
    }
    return processEngines.get(processEngineName);
  }

  /**
   * retries to initialize a process engine that previously failed.
   */
  public static ProcessEngineInfo retry(String resourceUrl) {
    log.debug("retying initializing of resource {}", resourceUrl);
    try {
      return initProcessEngineFromResource(new URL(resourceUrl));
    } catch (MalformedURLException e) {
      throw new ActivitiIllegalArgumentException("invalid url: " + resourceUrl, e);
    }
  }

  /**
   * provides access to process engine to application clients in a managed server environment.
   */
  public static Map<String, ProcessEngine> getProcessEngines() {
    return processEngines;
  }

  /**
   * closes all process engines. This method should be called when the server shuts down.
   */
  public synchronized static void destroy() {
    if (isInitialized()) {
      Map<String, ProcessEngine> engines = new HashMap<String, ProcessEngine>(processEngines);
      processEngines = new HashMap<String, ProcessEngine>();

      for (String processEngineName : engines.keySet()) {
        ProcessEngine processEngine = engines.get(processEngineName);
        try {
          processEngine.close();
        } catch (Exception e) {
          log.error("exception while closing {}", (processEngineName == null ? "the default process engine" : "process engine " + processEngineName), e);
        }
      }

      processEngineInfosByName.clear();
      processEngineInfosByResourceUrl.clear();
      processEngineInfos.clear();

      setInitialized(false);
    }
  }

  public static boolean isInitialized() {
    return isInitialized;
  }

  public static void setInitialized(boolean isInitialized) {
    ProcessEngines.isInitialized = isInitialized;
  }
}

4.ProcessEngineLifecycleListener

public interface ProcessEngineLifecycleListener {

  /**
   * Called right after the process-engine has been built.
   *
   * @param processEngine
   *          engine that was built
   */
  void onProcessEngineBuilt(ProcessEngine processEngine);

  /**
   * Called right after the process-engine has been closed.
   *
   * @param processEngine
   *          engine that was closed
   */
  void onProcessEngineClosed(ProcessEngine processEngine);
}

5.ProcessEngines

public abstract class ProcessEngines {

  private static Logger log = LoggerFactory.getLogger(ProcessEngines.class);

  public static final String NAME_DEFAULT = "default";

  protected static boolean isInitialized;
  protected static Map<String, ProcessEngine> processEngines = new HashMap<String, ProcessEngine>();
  protected static Map<String, ProcessEngineInfo> processEngineInfosByName = new HashMap<String, ProcessEngineInfo>();
  protected static Map<String, ProcessEngineInfo> processEngineInfosByResourceUrl = new HashMap<String, ProcessEngineInfo>();
  protected static List<ProcessEngineInfo> processEngineInfos = new ArrayList<ProcessEngineInfo>();

  /**
   * Initializes all process engines that can be found on the classpath for resources <code>activiti.cfg.xml</code> (plain Activiti style configuration) and for resources
   * <code>activiti-context.xml</code> (Spring style configuration).
   */
  public synchronized static void init() {
    if (!isInitialized()) {
      if (processEngines == null) {
        // Create new map to store process-engines if current map is
        // null
        processEngines = new HashMap<String, ProcessEngine>();
      }
      ClassLoader classLoader = ReflectUtil.getClassLoader();
      Enumeration<URL> resources = null;
      try {
        resources = classLoader.getResources("activiti.cfg.xml");
      } catch (IOException e) {
        throw new ActivitiIllegalArgumentException("problem retrieving activiti.cfg.xml resources on the classpath: " + System.getProperty("java.class.path"), e);
      }

      // Remove duplicated configuration URL's using set. Some
      // classloaders may return identical URL's twice, causing duplicate
      // startups
      Set<URL> configUrls = new HashSet<URL>();
      while (resources.hasMoreElements()) {
        configUrls.add(resources.nextElement());
      }
      for (Iterator<URL> iterator = configUrls.iterator(); iterator.hasNext();) {
        URL resource = iterator.next();
        log.info("Initializing process engine using configuration '{}'", resource.toString());
        initProcessEngineFromResource(resource);
      }

      try {
        resources = classLoader.getResources("activiti-context.xml");
      } catch (IOException e) {
        throw new ActivitiIllegalArgumentException("problem retrieving activiti-context.xml resources on the classpath: " + System.getProperty("java.class.path"), e);
      }
      while (resources.hasMoreElements()) {
        URL resource = resources.nextElement();
        log.info("Initializing process engine using Spring configuration '{}'", resource.toString());
        initProcessEngineFromSpringResource(resource);
      }

      setInitialized(true);
    } else {
      log.info("Process engines already initialized");
    }
  }

  protected static void initProcessEngineFromSpringResource(URL resource) {
    try {
      Class<?> springConfigurationHelperClass = ReflectUtil.loadClass("org.activiti.spring.SpringConfigurationHelper");
      Method method = springConfigurationHelperClass.getDeclaredMethod("buildProcessEngine", new Class<?>[] { URL.class });
      ProcessEngine processEngine = (ProcessEngine) method.invoke(null, new Object[] { resource });

      String processEngineName = processEngine.getName();
      ProcessEngineInfo processEngineInfo = new ProcessEngineInfoImpl(processEngineName, resource.toString(), null);
      processEngineInfosByName.put(processEngineName, processEngineInfo);
      processEngineInfosByResourceUrl.put(resource.toString(), processEngineInfo);

    } catch (Exception e) {
      throw new ActivitiException("couldn't initialize process engine from spring configuration resource " + resource.toString() + ": " + e.getMessage(), e);
    }
  }

  /**
   * Registers the given process engine. No {@link ProcessEngineInfo} will be available for this process engine. An engine that is registered will be closed when the {@link ProcessEngines#destroy()}
   * is called.
   */
  public static void registerProcessEngine(ProcessEngine processEngine) {
    processEngines.put(processEngine.getName(), processEngine);
  }

  /**
   * Unregisters the given process engine.
   */
  public static void unregister(ProcessEngine processEngine) {
    processEngines.remove(processEngine.getName());
  }

  private static ProcessEngineInfo initProcessEngineFromResource(URL resourceUrl) {
    ProcessEngineInfo processEngineInfo = processEngineInfosByResourceUrl.get(resourceUrl.toString());
    // if there is an existing process engine info
    if (processEngineInfo != null) {
      // remove that process engine from the member fields
      processEngineInfos.remove(processEngineInfo);
      if (processEngineInfo.getException() == null) {
        String processEngineName = processEngineInfo.getName();
        processEngines.remove(processEngineName);
        processEngineInfosByName.remove(processEngineName);
      }
      processEngineInfosByResourceUrl.remove(processEngineInfo.getResourceUrl());
    }

    String resourceUrlString = resourceUrl.toString();
    try {
      log.info("initializing process engine for resource {}", resourceUrl);
      ProcessEngine processEngine = buildProcessEngine(resourceUrl);
      String processEngineName = processEngine.getName();
      log.info("initialised process engine {}", processEngineName);
      processEngineInfo = new ProcessEngineInfoImpl(processEngineName, resourceUrlString, null);
      processEngines.put(processEngineName, processEngine);
      processEngineInfosByName.put(processEngineName, processEngineInfo);
    } catch (Throwable e) {
      log.error("Exception while initializing process engine: {}", e.getMessage(), e);
      processEngineInfo = new ProcessEngineInfoImpl(null, resourceUrlString, getExceptionString(e));
    }
    processEngineInfosByResourceUrl.put(resourceUrlString, processEngineInfo);
    processEngineInfos.add(processEngineInfo);
    return processEngineInfo;
  }

  private static String getExceptionString(Throwable e) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    return sw.toString();
  }

  private static ProcessEngine buildProcessEngine(URL resource) {
    InputStream inputStream = null;
    try {
      inputStream = resource.openStream();
      ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream);
      return processEngineConfiguration.buildProcessEngine();

    } catch (IOException e) {
      throw new ActivitiIllegalArgumentException("couldn't open resource stream: " + e.getMessage(), e);
    } finally {
      IoUtil.closeSilently(inputStream);
    }
  }

  /** Get initialization results. */
  public static List<ProcessEngineInfo> getProcessEngineInfos() {
    return processEngineInfos;
  }

  /**
   * Get initialization results. Only info will we available for process engines which were added in the {@link ProcessEngines#init()}. No {@link ProcessEngineInfo} is available for engines which were
   * registered programatically.
   */
  public static ProcessEngineInfo getProcessEngineInfo(String processEngineName) {
    return processEngineInfosByName.get(processEngineName);
  }

  public static ProcessEngine getDefaultProcessEngine() {
    return getProcessEngine(NAME_DEFAULT);
  }

  /**
   * obtain a process engine by name.
   *
   * @param processEngineName
   *          is the name of the process engine or null for the default process engine.
   */
  public static ProcessEngine getProcessEngine(String processEngineName) {
    if (!isInitialized()) {
      init();
    }
    return processEngines.get(processEngineName);
  }

  /**
   * retries to initialize a process engine that previously failed.
   */
  public static ProcessEngineInfo retry(String resourceUrl) {
    log.debug("retying initializing of resource {}", resourceUrl);
    try {
      return initProcessEngineFromResource(new URL(resourceUrl));
    } catch (MalformedURLException e) {
      throw new ActivitiIllegalArgumentException("invalid url: " + resourceUrl, e);
    }
  }

在这里插入图片描述

参考资料和推荐阅读

[1].www.activite.org

欢迎阅读,各位老铁,如果对你有帮助,点个赞加个关注呗!~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详解Unity中的新版Nav Mesh|导航寻路系统 (三)

前言 通过前面两篇的介绍与讲解我们已经对新版NavMesh有了一个基础的了解和使用&#xff0c;本篇我们继续讲解剩余的两个组件NavMeshModifier、NavMeshModifierVolume&#xff0c;这两个组件是主要是用于影响导航网格的生成的。所以内容不是很主要&#xff0c;但也非常重要。 …

LQ0209 颠倒的价牌【枚举+进制】

题目来源&#xff1a;蓝桥杯2013初赛 C A组D题 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小李的店里专卖其它店中下架的样品电视机&#xff0c;可称为&#xff1a;样品电视专卖店。 其标价都是 4 位数字&am…

Pulsar bundle数目的选择

看到今年Pulsar 峰会上挺多人分享负载均衡的内容&#xff0c;这里也整理分享一下相关的内容。 实践中&#xff0c;我们都会 关闭 auto bundle split&#xff0c;保证系统稳定 Pulsar bundle split 是一个比较耗费资源的操作&#xff0c;会造成连接到这个 bundle 上的所有 pr…

SAP 物料分类账配置详解Part 1( 基于SAP S/4HANA1909 版本)

本文将详细介绍&#xff1a;SAP 物料分类账配置要点 &#xff0c;本系统使用的版本是&#xff1a; SAP S/4HANA1909 版本目录 1 物料分类账的后台配置 1.1 激活物料分类帐的评估区域 1.2 分配货币类型并定义物料分类帐类型 1.3 分配物料分类帐类型给评估范围 1.5 定义…

m基于MATLAB的通信系统仿真,包括信号源,载波信号,放大器,带宽滤波器,接收端包括放大器,带宽滤波器,载波解调,低通滤波器等

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 Interference : 200KHz Signal source: 需要在给出的一个excel 文档里调用&#xff0c;我对应的信号是第二竖栏&#xff0c;就是从B1到B60 里面所有的filter(滤波器)都是自己来选值&am…

驱动 私有数据传参点灯

1.在串口工具进行输入&#xff1a; echo 1 > /dev/myled0 ---->led1灯点亮 echo 0 > /dev/myled0 ---->led1灯熄灭 echo 1 > /dev/myled1 ---->led1灯点亮 echo 0 > /dev/myled1 ---->led1灯熄灭 echo 1 > /dev/myled2 ----…

243 h160 相交链表

题解 本题关键: acbbca // 243 h160 相交链表public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode pointAheadA,pointBheadB;int rount2;while (rount>0){if (pointApointB){return pointA;}pointApointA.next;pointBpointB.next;if (pointAnul…

【树莓派不吃灰】命令篇⑥ 了解树莓派Boot分区,学习Linux启动流程

目录1. Linux启动过程1.1 内核引导1.2 运行init初始化进程 —— 初始化系统环境1.3 运行级别 —— runlevel1.4 系统初始化 —— 加载开机启动程序1.5 用户登录1.5.1 方式1&#xff1a;命令行登录1.5.2 方式2&#xff1a;ssh登录&#xff08;常用&#xff09;1.5.3 方式3&#…

[附源码]计算机毕业设计JAVA恒星学院网络计费系统

[附源码]计算机毕业设计JAVA恒星学院网络计费系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM my…

Lingo软硬件划分 实例

文章目录一、SM2 加密算法软硬件划分1.1 实验目标1.2 实验过程&#xff08;1&#xff09; 综合考虑使得系统整体性能最&#xff08;2&#xff09;只考虑硬面积&#xff0c;即系统硬件面积最小&#xff08;3&#xff09;只考虑功耗&#xff0c;即系统功耗最小&#xff08;4&…

SpringBoot实用开发篇复习4(实用开发篇完)

在上面一节&#xff0c;我们学习了SpringBoot整合第三方技术&#xff0c;这次我们主要学习监控技术&#xff0c;主要包含四个部分&#xff0c;分别为监控的意义&#xff0c;可视化监控平台&#xff0c;监控的原理&#xff0c;自定义监控指标等&#xff0c;下面一起来学习吧。 …

nodejs+vue+elementui前台美食网上订餐点菜系统 vscode项目

前端技术&#xff1a;nodejsvueelementui 前端&#xff1a;HTML5,CSS3、JavaScript、VUE 系统分为不同的层次&#xff1a;视图层&#xff08;vue页面&#xff09;&#xff0c;表现层&#xff08;控制器类&#xff09;&#xff0c;业务层&#xff08;接口类&#xff09;和持久层…

SSM框架+LayUi+Mysql实现的物流配送管理系统(功能包含分角色,登录/注册、车辆管理/路线管理/运单管理/调度安排/信息管理等)

博客目录SSM框架LayUiMysql实现的物流配送管理系统实现功能截图系统功能使用技术代码完整源码SSM框架LayUiMysql实现的物流配送管理系统 本系统为了解决物流平台的配送难题&#xff0c;将司机/物流配送的整体流程话&#xff0c;便于物流公司的统一管理&#xff0c;提高了物流日…

JUC学习笔记——共享模型之内存

在本系列内容中我们会对JUC做一个系统的学习&#xff0c;本片将会介绍JUC的内存部分 我们会分为以下几部分进行介绍&#xff1a; Java内存模型可见性模式之两阶段终止模式之Balking原理之指令级并行有序性volatile原理 Java内存模型 我们首先来介绍一下Java内存模型&#xf…

博途1200PLC编码器速度信号采集和滤波处理

速度估算有M法和T法测速2种常用方法,工业控制PLC上基本采用M法测速,M法测速的详细原理,这里不再赘述。感兴趣的可以参看下面的文章链接: PLC通过编码器反馈值计算速度的推荐做法(算法解析+ST代码)_RXXW_Dor的博客-CSDN博客PLC如何测量采集编码器的位置数据,不清楚的可以…

spring框架源码十七、Bean对象创建子流程

Bean对象创建子流程Bean对象创建子流程new ClassPathXmlApplicationContextClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String)ClassPathXmlApplicationContext#ClassPathXmlApplicationContext(java.lang.String[], boolean, org.springframew…

冒泡事件在Vue中的应用

什么是事件冒泡&#xff1f; 一想到“冒泡”这两个词会想到什么&#xff1f;想必然&#xff0c;那就是气泡自下而上的从水底往上生的场景&#xff0c;但是我们也知道&#xff0c;水在往上升的过程中&#xff0c;也会经历不同的高度。由此场景&#xff0c;那么想必然&#xff0c…

JavaEE 进阶:Spring 核⼼与设计思想

文章目录一、Spring 是什么1、什么是容器2、什么是 IoC① 传统程序开发Ⅰ 轮胎尺寸固定a. 代码b. 缺陷Ⅱ 轮胎尺寸改变a. 代码b. 缺陷② 控制反转式程序开发Ⅰ 控制反转Ⅱ 需求增加Ⅲ 优点③ 对⽐总结规律3、理解 Spring IoC4、DI 概念说明一、Spring 是什么 Spring是当前Java…

Windows安装nginx

Windows安装nginx1.下载Nginx2.Nginx的使用2.1 修改nginx.conf2.2 启动nginx3.可能出现的问题观前提示&#xff1a; 本文所使用的系统Windows10。 1.下载Nginx Nginx官网&#xff0c;点击download下载 根据需求下载自己所需版本&#xff0c;这里我下载的是稳定版本 2.Nginx的…

链表

章节目录&#xff1a;一、链表1.1 概述二、单向链表2.1 实现思路2.2 代码示例三、双向链表3.1 实现思路3.2 代码示例四、单向环形链表4.1 约瑟夫问题4.2 实现思路4.3 代码示例五、结束语一、链表 1.1 概述 链表是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;数据元…