Java Activiti 指南

1.概述

Activiti API 是一个工作流和业务流程管理系统。我们可以在其中定义一个流程,执行它,并使用 API 提供的服务以不同的方式对其进行操作。它需要JDK 7+。

可以在任何 IDE 中使用 API 进行开发,但是要使用Activiti Designer,我们需要 Eclipse。

我们可以使用 BPMN 2.0 标准在其中定义一个流程。还有另一种不太流行的方法——使用 Java 类,如StartEventEndEventUserTaskSequenceFlow等。

如果我们想运行一个流程或访问任何服务,我们需要创建一个ProcessEngineConfiguration

在某些方面,我们可以使用ProcessEngineConfiguration获取ProcessEngine,我们将在本文中进一步讨论通过ProcessEngine我们可以执行Workflow 和 BPMN 操作。

2.Maven依赖

要使用这个 API,我们需要包含 Activiti 依赖:

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-engine</artifactId>
</dependency>

3. 创建流程引擎

Activiti 中的ProcessEngine通常使用 XML 文件activiti.cfg.xml进行配置。此配置文件的一个示例是:

<beans xmlns="...">
    <bean id="processEngineConfiguration" class=
      "org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcUrl" 
          value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
        <property name="jdbcDriver" value="org.h2.Driver" />
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="" />
        <property name="databaseSchemaUpdate" value="true" />
    </bean>
</beans>

现在我们可以使用ProcessEngines类获取ProcessEngine :

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

该语句将查找activiti.cfg。在classpath中添加一个xml文件,并根据文件中的配置构造一个ProcessEngine

配置文件的示例代码表明它只是一个基于 Spring 的配置。但是,这并不意味着我们只能在 Spring 环境中使用 Activiti。Spring 的功能只是在内部用于创建ProcessEngine

让我们编写一个 JUnit 测试用例,它将使用上面显示的配置文件创建ProcessEngine :

@Test
public void givenXMLConfig_whenGetDefault_thenGotProcessEngine() {
    ProcessEngine processEngine 
      = ProcessEngines.getDefaultProcessEngine();
    assertNotNull(processEngine);
    assertEquals("root", processEngine.getProcessEngineConfiguration()
      .getJdbcUsername());
}

4. Activiti 流程引擎 API 和服务

与 API 交互的入口点是ProcessEngine。通过ProcessEngine,我们可以访问各种提供工作流/BPMN 方法的服务。ProcessEngine和所有服务对象都是线程安全的。

取自 https://www.activiti.org/userguide/images/api.services.png

 

ProcessEngines类将扫描activiti.cfg.xmlactiviti -context.xml文件。如前所述,对于所有的activiti.cfg.xml文件,ProcessEngine将以典型的方式创建。

然而,对于所有activiti-context.xml文件,它将以 Spring 方式创建——我将创建 Spring Application Context 并从中获取ProcessEngine。在流程执行期间,将按照 BPMN 文件中定义的顺序访问所有步骤。

在流程执行期间,将按照 BPMN 文件中定义的顺序访问所有步骤。

4.1。流程定义和相关术语

ProcessDefinition代表一个业务流程。它用于定义流程中不同步骤的结构和行为。部署流程定义意味着将流程定义加载到 Activiti 数据库中。

流程定义主要由 BPMN 2.0 标准定义。也可以使用 Java 代码定义它们。本节中定义的所有术语也可以作为 Java 类使用。

一旦我们开始运行一个流程定义,它就可以被称为一个流程

ProcessInstanceProcessDefinition的一种执行。

StartEvent与每个业务流程相关联。它表示进程的入口点。类似地,有一个EndEvent指示进程的结束。我们可以定义这些事件的条件。

开始和结束之间的所有步骤(或元素)都称为任务任务可以是各种类型。最常用的任务是UserTasksServiceTasks

顾名思义, UserTasks需要用户手动执行。

另一方面,ServiceTasks是用一段代码配置的。每当执行到达他们时,他们的代码块就会被执行。

SequenceFlows连接任务。我们可以通过它们将连接的源元素和目标元素来定义序列流。同样,我们还可以在SequenceFlows上定义条件以在流程中创建条件路径。

4.2. 服务

我们将简要讨论 Activiti 提供的服务:

  • RepositoryService帮助我们操纵流程定义的部署。该服务处理与流程定义相关的静态数据
  • RuntimeService管理ProcessInstances(当前正在运行的进程)以及进程变量
  • TaskService跟踪UserTasks。需要用户手动执行的任务是 Activiti API 的核心。我们可以使用此服务创建任务、声明并完成任务、操作任务的受让人等
  • FormService是一项可选服务。API 可以在没有它的情况下使用,并且不会牺牲它的任何特性。它用于定义流程中的开始形式和任务形式。
  • IdentityService管理用户
  • HistoryService跟踪 Activiti Engine 的历史。我们还可以设置不同的历史级别。
  • ManagementService与元数据相关,通常在创建应用程序时不需要
  • DynamicBpmnService帮助我们更改流程中的任何内容,而无需重新部署它

5. 使用 Activiti 服务

为了了解我们如何使用不同的服务并运行一个流程,让我们以“员工休假请求”的流程为例:

 

该流程的 BPMN 2.0 文件VacationRequest.bpmn20.xml将开始事件定义为:

<startEvent id="startEvent" name="request" 
  activiti:initiator="employeeName">
    <extensionElements>
        <activiti:formProperty id="numberOfDays" 
          name="Number of days" type="long" required="true"/>
        <activiti:formProperty id="startDate" 
          name="Vacation start date (MM-dd-yyyy)" type="date" 
          datePattern="MM-dd-yyyy hh:mm" required="true"/>
        <activiti:formProperty id="reason" name="Reason for leave" 
          type="string"/>
     </extensionElements>
</startEvent>

同样,分配给用户组“管理”的第一个用户任务将如下所示:

<userTask id="handle_vacation_request" name=
  "Handle Request for Vacation">
    <documentation>${employeeName} would like to take ${numberOfDays} day(s)
      of vacation (Motivation: ${reason}).</documentation>
    <extensionElements>
        <activiti:formProperty id="vacationApproved" name="Do you approve
          this vacation request?" type="enum" required="true"/>
        <activiti:formProperty id="comments" name="Comments from Manager"
          type="string"/>
    </extensionElements>
    <potentialOwner>
      <resourceAssignmentExpression>
        <formalExpression>management</formalExpression>
      </resourceAssignmentExpression>
    </potentialOwner>
</userTask>

使用ServiceTask,我们需要定义要执行的代码。我们将这段代码作为 Java 类:

<serviceTask id="send-email-confirmation" name="Send email confirmation" 
  activiti:class=
  "com.example.activiti.servicetasks.SendEmailServiceTask.java">
</serviceTask>

条件流将通过在“sequenceFlow”中添加“conditionExpression”标签来显示:

<sequenceFlow id="flow3" name="approved" 
  sourceRef="sid-12A577AE-5227-4918-8DE1-DC077D70967C" 
  targetRef="send-email-confirmation">
    <conditionExpression xsi:type="tFormalExpression">
      <![CDATA[${vacationApproved == 'true'}]]>
    </conditionExpression>
</sequenceFlow>

在这里,vacationApproved是上面显示的UserTask的formProperty

正如我们在图中看到的,这是一个非常简单的过程。员工提出休假请求,提供休假天数和开始日期。请求发送给经理。他们可以批准/拒绝该请求。

如果获得批准,则会定义一个服务任务来发送确认电子邮件。如果未获批准,员工可以选择修改并重新发送请求,或者什么也不做。

为服务任务提供了一些要执行的代码(这里,作为 Java 类)。我们已经给出了SendEmailServiceTask.java 类。

这些类型的类应该扩展JavaDelegate。另外,我们需要重写它的execute()方法,这个方法会在流程执行到这一步时执行。

5.1。部署流程

为了让 Activiti 引擎知道我们的流程,我们需要部署流程。我们可以使用RepositoryService 以编程方式完成。让我们编写一个 JUnit 测试来展示这一点:

@Test 
public void givenBPMN_whenDeployProcess_thenDeployed() {
    ProcessEngine processEngine 
      = ProcessEngines.getDefaultProcessEngine();
    RepositoryService repositoryService 
      = processEngine.getRepositoryService();
    repositoryService.createDeployment()
      .addClasspathResource(
      "org/activiti/test/vacationRequest.bpmn20.xml")
      .deploy();
    Long count=repositoryService.createProcessDefinitionQuery().count();
    assertEquals("1", count.toString());
}

部署意味着引擎将解析 BPMN 文件并将其转换为可执行文件。此外,每次部署都会在存储库表中添加一条记录。

因此,之后,我们可以查询Repository服务以获取已部署的进程;过程定义

5.2. 启动ProcessInstance

将ProcessDefinition部署到 Activiti Engine 后,我们可以通过创建ProcessInstances来执行流程。ProcessDefinition是一个蓝图,ProcessInstance是它的运行时执行。

对于单个ProcessDefinition,可以有多个ProcessInstances

可以通过RuntimeService访问与ProcessInstances相关的所有详细信息。

在我们的示例中,在开始事件中,我们需要传递休假天数、开始日期和原因。我们将使用流程变量,并在创建ProcessInstance 时传递它们。

让我们编写一个 JUnit 测试用例以获得更好的想法:

@Test
public void givenDeployedProcess_whenStartProcessInstance_thenRunning() {
    //deploy the process definition    
    Map<String, Object> variables = new HashMap>();
    variables.put("employeeName", "John");
    variables.put("numberOfDays", 4);
    variables.put("vacationMotivation", "I need a break!");
    
    RuntimeService runtimeService = processEngine.getRuntimeService();
    ProcessInstance processInstance = runtimeService
      .startProcessInstanceByKey("vacationRequest", variables);
    Long count=runtimeService.createProcessInstanceQuery().count();
 
    assertEquals("1", count.toString());
}

单个流程定义的多个实例将因流程变量而异。

有多种方法可以启动流程实例。在这里,我们使用的是进程的密钥。启动流程实例后,我们可以通过查询RuntimeService来获取它的相关信息。

5.3. 完成任务

当我们的流程实例开始运行时,第一步是一个用户任务,分配给用户组“管理”。

用户可能有一个收件箱,其中包含他们要完成的任务列表。现在,如果我们想继续流程执行,用户需要完成这个任务。对于 Activiti Engine,它被称为“完成任务”。

我们可以查询TaskService,获取任务对象,然后完成它。

我们需要为此编写的代码如下所示:

@Test 
public void givenProcessInstance_whenCompleteTask_thenGotNextTask() {
    // deploy process and start process instance   
    TaskService taskService = processEngine.getTaskService();
    List<Task> tasks = taskService.createTaskQuery()
      .taskCandidateGroup("management").list();
    Task task = tasks.get(0);
    
    Map<String, Object> taskVariables = new HashMap<>();
    taskVariables.put("vacationApproved", "false");
    taskVariables.put("comments", "We have a tight deadline!");
    taskService.complete(task.getId(), taskVariables);

    Task currentTask = taskService.createTaskQuery()
      .taskName("Modify vacation request").singleResult();
    assertNotNull(currentTask);
}

请注意,TaskService的complete()方法也接受所需的流程变量。我们传递了经理的答复。

在此之后,流程引擎将继续进行下一步。在这里,下一步询问员工是否要重新发送休假请求。

因此,我们的ProcessInstance现在正在等待这个名为“修改假期请求”的UserTask 。

5.4. 暂停和激活进程

我们可以暂停ProcessDefinitionProcessInstance。如果我们挂起一个ProcessDefinition,我们就不能在它挂起时创建它的实例。我们可以使用RepositoryService 做到这一点:

@Test(expected = ActivitiException.class)
public void givenDeployedProcess_whenSuspend_thenNoProcessInstance() {
    // deploy the process definition
    repositoryService.suspendProcessDefinitionByKey("vacationRequest");
    runtimeService.startProcessInstanceByKey("vacationRequest");
}	

要再次激活它,我们只需要调用repositoryService.activateProcessDefinitionXXX方法之一。

同样,我们可以使用RuntimeService挂起ProcessInstance 。

6. 结论

在本文中,我们看到了如何将 Activiti 与 Java 一起使用。我们创建了一个示例ProcessEngineCofiguration文件,它可以帮助我们创建ProcessEngine

使用它,我们访问了 API 提供的各种服务。这些服务帮助我们管理和跟踪ProcessDefinitionsProcessInstancesUserTasks等。

与往常一样,我们在文章中看到的示例代码位于GitHub 上

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Activiti 是一个流程引擎框架,可以帮助开发者快速实现工作流相关的应用。下面是使用 Activiti 创建流程引擎的步骤: 1. 创建 maven 项目,添加 Activiti 依赖。 在项目的 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>5.22.0</version> </dependency> ``` 2. 创建流程引擎配置类。 在项目中创建一个 Java 类,用于配置流程引擎。可以在该类中指定数据库连接信息、流程图文件路径等信息。以下是一个示例配置类: ``` import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration; public class ActivitiConfig { public ProcessEngine getProcessEngine() throws IOException { // 读取配置文件 InputStream inputStream = getClass().getResourceAsStream("/activiti.properties"); Properties properties = new Properties(); properties.load(inputStream); // 配置流程引擎 ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration() .setJdbcUrl(properties.getProperty("jdbc.url")) .setJdbcUsername(properties.getProperty("jdbc.username")) .setJdbcPassword(properties.getProperty("jdbc.password")) .setJdbcDriver(properties.getProperty("jdbc.driver")) .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE); // 创建流程引擎 ProcessEngine processEngine = cfg.buildProcessEngine(); return processEngine; } } ``` 在该配置类中,我们读取一个名为 activiti.properties 的配置文件,该文件包含了数据库连接信息。在实际开发中,我们可以将这些信息存储在外部配置文件中,以便于修改和管理。 3. 创建流程图文件。 使用 Activiti Modeler 工具创建流程图文件,或者手动编写 BPMN 2.0 标准的 XML 文件。将该文件放置在项目的 classpath 下,以便于程序能够读取。 4. 启动流程引擎。 在程序中使用上述配置类创建流程引擎实例,并启动该实例。以下是一个示例代码: ``` public static void main(String[] args) throws IOException { // 创建流程引擎配置类 ActivitiConfig config = new ActivitiConfig(); // 获取流程引擎实例 ProcessEngine processEngine = config.getProcessEngine(); // 输出流程引擎信息 String name = processEngine.getName(); String version = ProcessEngine.VERSION; System.out.println("流程引擎名称:" + name); System.out.println("流程引擎版本:" + version); // 关闭流程引擎 processEngine.close(); } ``` 在上述示例代码中,我们创建了一个 ActivitiConfig 实例,并使用该实例获取了流程引擎。获取流程引擎后,我们可以输出其名称和版本信息,并在程序结束时关闭该引擎。 以上就是使用 Activiti 创建流程引擎的步骤。开发者可以根据自己的需求对流程引擎进行配置和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值