flowable的基础使用

1、添加flowable引擎依赖和数据库依赖


<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-engine</artifactId>
<version>...</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId
<version>....</version>
</dependency>

2、实例化一个ProcessEngine实例


默认场景:引入flowable-spring-boot-starter 依赖+ 配置文件 -> 直接注入服务

高级场景:通过自定义配置类来创建bean对象:

@Configuration
public class FlowableConfig {

    @Bean
    public ProcessEngineConfiguration processEngineConfiguration(DataSource dataSource, PlatformTransactionManager transactionManager) {
        SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration();
        config.setDataSource(dataSource);
        config.setTransactionManager(transactionManager);
        config.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        config.setAsyncExecutorActivate(true); // 启用异步执行器
        return config;
    }

    @Bean
    public ProcessEngine processEngine(ProcessEngineConfiguration config) {
        return config.buildProcessEngine();
    }

    // 其他服务(如RuntimeService)会自动从ProcessEngine中暴露为Bean
}

3、部署流程定义:

这里构建一个休假流程,flowable引擎使用BPMN2.0格式定义流程。从流程定义中,可以启动许多流程实例。将流程定义视为许多流程执行的蓝图。在这个特定的例子中,流程定义定义了请假所涉及的不同步骤,而一个流程实例匹配一个特定员工的休假请求。

BPMN 2.0 XML 格式存储,但它也有可视化部分:它以标准方式定义了如何表示每种不同的步骤类型(人工任务、自动服务调用等)以及如何将这些不同的步骤相互连接。

使用的流程定义如下:

我们假设流程是通过提供一些信息来启动的,比如员工姓名、请假天数和描述。

下面是与上图对应的 BPMN 2.0 XML。将以下 XML 保存在 src/main/resources 文件夹中名为 holiday-request.bpmn20.xml 的文件中。

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
  xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
  xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
  xmlns:flowable="http://flowable.org/bpmn"
  typeLanguage="http://www.w3.org/2001/XMLSchema"
  expressionLanguage="http://www.w3.org/1999/XPath"
  targetNamespace="http://www.flowable.org/processdef">

  <process id="holidayRequest" name="Holiday Request" isExecutable="true">

    <startEvent id="startEvent"/>
    <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>

    <userTask id="approveTask" name="Approve or reject request"/>
    <sequenceFlow sourceRef="approveTask" targetRef="decision"/>

    <exclusiveGateway id="decision"/>
    <sequenceFlow sourceRef="decision" targetRef="externalSystemCall">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[
          ${approved}
        ]]>
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow  sourceRef="decision" targetRef="sendRejectionMail">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[
          ${!approved}
        ]]>
      </conditionExpression>
    </sequenceFlow>

    <serviceTask id="externalSystemCall" name="Enter holidays in external system"
        flowable:class="org.flowable.CallExternalSystemDelegate"/>
    <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>

    <userTask id="holidayApprovedTask" name="Holiday approved"/>
    <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>

    <serviceTask id="sendRejectionMail" name="Send out rejection email"
        flowable:class="org.flowable.SendRejectionMail"/>
    <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>

    <endEvent id="approveEnd"/>

    <endEvent id="rejectEnd"/>

  </process>

</definitions>

第 2-11 行在几乎每个流程定义中看到的内容相同。

每个步骤(在 BPMN 2.0 术语中称为"活动")都有一个 id 属性,为其在 XML 文件中提供唯一标识符。所有活动也可以有一个可选的名称,这当然会增加可视化图表的可读性。

活动通过序列流连接,在可视化图表中是一个有向箭头。在执行流程实例时,执行将从开始事件流向下一个活动,遵循序列流

离开排他网关(带有 X 的菱形)的序列流明显很特殊:它们都有一个以表达式形式定义的条件(见第 25 和 32 行)。当流程实例执行到达这个网关时,将评估这些条件,并采用第一个解析为true的条件。这就是这里排他的含义:只选择一个。如果需要不同的路由行为,当然可以使用其他类型的网关。

这里写为表达式的条件形式为 ${approved},这是 ${approved == true} 的简写。变量 'approved' 被称为流程变量流程变量是与流程实例一起存储的持久数据,可以在流程实例的生命周期内使用。在这种情况下,这确实意味着我们将必须在流程实例中的某个时刻(当经理用户任务被提交时,或者用 Flowable 术语说,完成时)设置这个流程变量,因为这不是流程实例启动时可用的数据。

接下来将BPMN2.0xml文件部署到引擎上:

这样一来流程引擎将xml文件存储在数据库中,以便在需要时就可以检索它;流程定义被解析为内部的、可执行的对象模型,以便可以从中启动流程实例

要将流程定义部署到 Flowable 引擎,使用 RepositoryService,它可以从 ProcessEngine 对象获取(如果注入的依赖是flowable-spring-boot-starter,那么可以不用从ProcessEngine中获取,直接注入即可)。使用 RepositoryService,通过传递 XML 文件的位置并调用 deploy() 方法来实际执行它,从而创建新的 Deployment:

RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment()
  .addClasspathResource("holiday-request.bpmn20.xml")
  .deploy();

同时我们也可以通过API查询来验证流程定义是否被引擎知晓,通过 RepositoryService 创建新的 ProcessDefinitionQuery 对象来完成

ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
  .deploymentId(deployment.getId())

 启动流程实例:

因为我们在定义流程时已经使用了需要流程变量才能触发的方式,所以这里我们就需要提供一些初始的流程变量来模拟触发:

Scanner scanner= new Scanner(System.in);

System.out.println("Who are you?");
String employee = scanner.nextLine();

System.out.println("How many holidays do you want to request?");
Integer nrOfHolidays = Integer.valueOf(scanner.nextLine());

System.out.println("Why do you need them?");
String description = scanner.nextLine();

这里我们可以使用RuntimeService来启动一个实例流程。使用HashMap来收集数据作为实例传递,使用启动流程实例。这个匹配在 BPMN 2.0 XML 文件中设置的 id 属性,在本例中是 holidayRequest。(稍后会了解到启动流程实例有很多方法,不仅仅是使用键

RuntimeService runtimeService = processEngine.getRuntimeService();

Map<String, Object> variables = new HashMap<String, Object>();
variables.put("employee", employee);
variables.put("nrOfHolidays", nrOfHolidays);
variables.put("description", description);
ProcessInstance processInstance =
  runtimeService.startProcessInstanceByKey("holidayRequest", variables);

这里创建RuntimeService实例是使用processEngine.getRuntimeService()方法得到的。如果注入的依赖是flowable-spring-boot-starter,可以直接注入得到

当流程实例启动时,将创建一个执行并放入开始事件中。从那里,这个执行沿着序列流到达经理审批的用户任务,并执行用户任务行为。这个行为将在数据库中创建一个任务,稍后可以通过查询找到。用户任务是一个等待状态,引擎将停止执行任何进一步的操作,返回 API 调用。

查询和完成任务:

在更现实的应用程序中,会有一个用户界面,员工和经理可以登录并查看他们的任务列表。通过这些列表,他们可以检查存储为流程变量的流程实例数据,并决定他们想对任务做什么。在这个例子中,我们将通过执行 API 调用来模拟任务列表,这些 API 调用通常会位于驱动 UI 的服务调用背后。

我们将第一个任务分配给"managers"组,在第一个任务中添加 candidateGroups 属性:

<userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/>

第二个用户任务分配给原始的假期申请人,并在第二个任务中添加 assignee 属性。这里没有使用像上面"managers"那样的静态值,而是使用基于流程变量的动态分配,这个流程变量是我们在启动流程实例时传递的

<userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/>

要获取实际的任务列表,我们通过 TaskService 创建一个 TaskQuery,并配置查询仅返回"managers"组的任务:

 

TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();

经理现在可以完成任务了。在现实中,这通常意味着用户提交了一个表单。然后表单中的数据作为流程变量传递。在这里,我们将通过在完成任务时传递一个带有"approved"变量的 map 来模拟这一点(名称很重要,因为它稍后会在序列流的条件中使用!):

boolean approved = scanner.nextLine().toLowerCase().equals("y");
variables = new HashMap<String, Object>();
variables.put("approved", approved);
taskService.complete(task.getId(), variables);

任务现在已完成,基于"approved"流程变量选择了离开排他网关的两条路径之一。

### Flowable 工作流引擎的使用方法 Flowable 是一种开源的工作流和业务流程管理 (BPM) 平台,广泛应用于 Java 应用程序中。它继承了 Activiti 的优点并进行了改进,提供了更强大的功能和支持[^2]。 以下是关于 Flowable 使用的一些核心概念和技术细节: #### 1. 流程定义与设计 Flowable 支持 BPMN 2.0 标准来描述业务流程模型。可以利用 Eclipse Designer 或其他工具创建 BPMN 文件,该文件包含了整个工作流的设计逻辑[^3]。通过图形化界面完成流程节点(如开始事件、结束事件、用户任务、服务任务等)以及连接线的配置后,将其部署到 Flowable 引擎上运行。 #### 2. 部署流程定义 要使自定义的 BPMN 过程生效,需调用 API 将其上传至服务器端。例如,在 Spring Boot 环境下可以通过如下方式实现: ```java RepositoryService repositoryService = processEngine.getRepositoryService(); repositoryService.createDeployment() .addClasspathResource("processes/my-process.bpmn20.xml") // 加载本地资源路径下的 bpmn 文件 .deploy(); // 执行部署动作 ``` #### 3. 启动实例与执行任务 一旦某个特定版本被成功注册,则可依据此模板发起新的实例,并按照既定顺序推进各个阶段的任务处理。 启动一个新的流程实例代码片段可能看起来像这样子: ```java RuntimeService runtimeService = processEngine.getRuntimeService(); Map<String, Object> variables = new HashMap<>(); variables.put("varName", value); // 设置变量参数传递给后续环节使用 ProcessInstance pi = runtimeService.startProcessInstanceByKey("myProcessKey", variables); System.out.println(pi.getId()); // 输出当前正在运转中的唯一标识符ID号 ``` 当到达某个人工干预型活动单元时(比如审批单填写),系统通常会暂停等待外部触发继续前进信号;此时开发者应该提供相应的前端页面让用户交互完成后提交数据反馈回去更新状态信息。 #### 4. 查询历史记录 为了跟踪已完成或者正在进行当中各项事务进展情况,有必要定期检索相关统计数据供管理层查看分析决策之用。History Service 提供了一系列的方法帮助我们获取这些必要的详情资料。 ```java HistoryService historyService = processEngine.getHistoryService(); List<HistoricActivityInstance> historicInstances = historyService.createHistoricActivityInstanceQuery().listPage(0, 100); for(HistoricActivityInstance hai :historicInstances){ System.out.println(hai.getActivityId()+" "+hai.getStartTime()); } ``` 以上仅展示了部分基础操作指南,实际项目开发过程中还需要深入学习官方文档了解更多高级特性和最佳实践建议[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值