Flowable:ProcessEngin(引擎)与Service(服务接口)讲解

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Flowable:ProcessEngin(引擎)与Service(服务接口)讲解

ProcessEngine 讲解

ProcessEngine 简介

ProcessEngine是Flowable的核心引擎,它是整个流程引擎的主入口。

ProcessEngine负责加载配置、管理流程定义、执行流程实例、处理任务等。通常,一个应用程序只需要一个ProcessEngine实例

ProcessEngine 实例创建

硬编码方式创建

首先通过ProcessEngineConfiguration这个配置类来加载Flowable要连接数据库的配置信息,然后再用ProcessEngine创建引擎对象

// 配置数据库相关信息 获取 ProcessEngineConfiguration
ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
    .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")
    .setJdbcUsername("root")
    .setJdbcPassword("123456")
    .setJdbcDriver("com.mysql.cj.jdbc.Driver")
    .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
// 获取流程引擎对象
ProcessEngine processEngine = cfg.buildProcessEngine();

这种方式会调用buildProcessEngine()方法,里面的核心代码为:

其中里面的Init函数会完成各种Flowable引擎初始化操作:

配置文件方式创建

除了上面的硬编码配置的方式创建引擎实例外,我们还可以在resources目录下创建一个flowable.cfg.xml文件,注意这个名称是固定的:

内容如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="processEngineConfiguration"
          class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/flow1?allowMultiQueries=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;serverTimezone=UTC&amp;nullCatalogMeansCurrent=true" /><property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" />
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="root" />
        <property name="databaseSchemaUpdate" value="true" />
        <property name="asyncExecutorActivate" value="false" />
    </bean>
</beans>

在上面的配置文件中配置相关的信息。我们在Java代码中就可以简化为:

@Test
public void test01(){
    // 获取流程引擎对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    System.out.println("processEngine = " + processEngine);
}

可以看下getDefaultProcessEngine的源码,在里面最终还是执行了和硬编码一样的代码

public static ProcessEngine getProcessEngine(String processEngineName) {
    if (!isInitialized()) {
        init(); // 完成初始化操作
    }
    return processEngines.get(processEngineName);
}

进入init方法

public static synchronized void init() {
    if (!isInitialized()) {
        if (processEngines == null) {
            // Create new map to store process-engines if current map is null
            processEngines = new HashMap<>();
        }
        ClassLoader classLoader = ReflectUtil.getClassLoader();
        Enumeration<URL> resources = null;
        try {
            resources = classLoader.getResources("flowable.cfg.xml"); // 加载flowable.cfg.xml配置文件
        } catch (IOException e) {
            throw new FlowableIllegalArgumentException("problem retrieving flowable.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<>();
        while (resources.hasMoreElements()) {
            configUrls.add(resources.nextElement());
        }
        for (Iterator<URL> iterator = configUrls.iterator(); iterator.hasNext();) {
            URL resource = iterator.next();
            LOGGER.info("Initializing process engine using configuration '{}'", resource.toString());
            initProcessEngineFromResource(resource); // 初始化ProcessEngine
        }
        try {
            resources = classLoader.getResources("flowable-context.xml"); // 在整合Spring的情况下加载该文件
        } catch (IOException e) {
            throw new FlowableIllegalArgumentException("problem retrieving flowable-context.xml resources on the classpath: " + System.getProperty("java.class.path"), e);
        }
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            LOGGER.info("Initializing process engine using Spring configuration '{}'", resource.toString());
            initProcessEngineFromSpringResource(resource); // 从Spring的资源文件中完成ProcessEngine的初始化
        }
        setInitialized(true);
    } else {
        LOGGER.info("Process engines already initialized");
    }
}

程序解读:Init方法的主要作用是在应用程序启动时初始化Flowable流程引擎,并加载配置文件来配置引擎的行为。让我解释一下其中的关键步骤和方法:

  1. public static synchronized void init():这是一个静态的同步方法,用于初始化流程引擎。同步保证了在多线程环境下只有一个线程可以执行初始化操作,以防止重复初始化。
  2. if (!isInitialized()):检查流程引擎是否已经初始化。如果已经初始化,就不再执行初始化操作。
  3. processEnginesprocessEngines 是一个 HashMap,用于存储初始化后的流程引擎实例。如果当前没有初始化过,会创建这个 HashMap
  4. ClassLoader classLoader = ReflectUtil.getClassLoader();:获取当前线程的类加载器,用于加载配置文件。
  5. Enumeration<URL> resources = classLoader.getResources("flowable.cfg.xml");:通过类加载器获取名为 “flowable.cfg.xml” 的配置文件资源。这个配置文件通常包含了流程引擎的各种配置信息,如数据库连接、流程定义等。
  6. Set<URL> configUrls = new HashSet<>();:创建一个 HashSet 用于存储配置文件的 URL,以去除重复的配置文件。
  7. 遍历配置文件资源,并将不重复的 URL 添加到 configUrls 中。
  8. LOGGER.info("Initializing process engine using configuration '{}'", resource.toString());:记录日志,表示正在初始化流程引擎,并打印使用的配置文件的路径。
  9. initProcessEngineFromResource(resource);:调用 initProcessEngineFromResource 方法来初始化流程引擎,这个方法根据配置文件创建流程引擎实例。
  10. 类似地,代码也加载名为 “flowable-context.xml” 的 Spring 配置文件,如果在应用程序中使用了 Spring 框架来集成 Flowable。
  11. setInitialized(true);:在完成流程引擎的初始化后,将初始化状态标记为 true,表示已经初始化。
  12. 最后,如果流程引擎已经初始化过,会记录日志表示已经初始化,不再执行初始化操作。

在源码中提供了单独使用好整合Spring的配置加载方式。再进入到initProcessEngineFromResource(resource)方法中:

然后我们进入到buildProcessEngine函数中,这里就能看到和我们之前硬编码的配置一样了

在进入buildProcessEngine函数,发现和之前进入的一样

所以,我们可以看到ProcessEngine最终的实现都是 ProcessEngineImpl对象。

自定义配置文件

除了按照规定名字去设置我们的配置文件,我们如果要加载自定义名称的配置文件可以通过ProcessEngineConfiguration中的对应构造方法来实现,如下是代码:

@Test
public void test2() throws Exception{
    ProcessEngineConfiguration configuration = ProcessEngineConfiguration
        .createProcessEngineConfigurationFromResource("flowable.cfg.xml");
    ProcessEngine processEngine = configuration.buildProcessEngine();
    System.out.println("processEngine = " + processEngine);
}

Servcie 服务接口

Servcie 服务接口简介

Service是工作流引擎提供用于进行工作流部署、执行、管理的服务接口,我们使用这些接口可以就是操作服务对应的数据表

Service 创建方式

通过ProcessEngine创建Service

方式如下:

RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
// ...
• 1
• 2
• 3
• 4

Service 总览

service名称 service作用
RepositoryService Flowable的资源管理类
RuntimeService Flowable的流程运行管理类
TaskService Flowable的任务管理类
HistoryService Flowable的历史管理类
ManagerService Flowable的引擎管理类
IdentityService Flowable的用户组管理类

Service 解释说明

  • RepositoryService
    RepositoryService是资源管理类,提供了管理和控制流程发布包和流程定义的操作。使用工作流建模工具设计的业务流程图需要使用此service将流程定义文件的内容部署到计算机。
    除了部署流程定义以外还可以:查询引擎中的发布包和流程定义。
    暂停或激活发布包,对应全部和特定流程定义。 暂停意味着它们不能再执行任何操作了,激活是对应的反向操作。获得多种资源,像是包含在发布包里的文件, 或引擎自动生成的流程图。
    获得流程定义的pojo版本, 可以用来通过java解析流程,而不必通过xml。
  • RuntimeService
    RuntimeService用于启动和管理流程实例的执行。您可以使用RuntimeService来启动新的流程实例、查询和管理流程实例的状态,以及执行流程的各个任务。
  • TaskService
    TaskService用于管理流程任务,包括查询、分配、完成任务等。您可以使用TaskService来与流程中的用户任务进行交互。
  • HistoryService
    Flowable的历史管理类,可以查询历史信息,执行流程时,引擎会保存很多数据(根据配置),比如流程实例启动时间,任务的参与者, 完成任务的时间,每个流程实例的执行路径,等等。 这个服务主要通过查询功能来获得这些数据。
  • ManagementService
    ManagementService是引擎管理类,提供了对Flowable 流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于 Flowable 系统的日常维护。
  • IdentityService:
    IdentityService用于管理用户和组,以便将其分配给流程中的任务或角色。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
Kubernetes Dubbo 应用服务中间件
Dubbo3实践:基于 API-SERVER 的原生 K8S Service
> 该示例演示了直接以 API-SERVER 为注册中心,将 Dubbo 应用部署到 Kubernetes 并复用 Kubernetes Native Service 的使用示例。 > > 此示例的局限在于需要授予每个 Dubbo 应用访问 API-SERVER 特定资源的权限,同时直接访问和监听 API-SERVER 对中小集群来说并没有什么问题,但对于较大规模集群而言可能给 API-SERV
478 0
|
8月前
|
Kubernetes 监控 Cloud Native
k8s 自身原理之 Service
k8s 自身原理之 Service
|
8月前
|
Kubernetes 网络协议 Cloud Native
Service 基础
Service 基础
|
API 开发工具 Android开发
Service基础
Service基础
66 0
Service基础
|
存储 负载均衡 Kubernetes
简单说说K8S的Service底层,总感觉还是说不清楚。
简单说说K8S的Service底层,总感觉还是说不清楚。
170 0
|
Kubernetes 前端开发 应用服务中间件
K8S 集群核心概念 Service_Service 介绍 | 学习笔记
快速学习 K8S 集群核心概念 Service_Service 介绍
118 0
K8S 集群核心概念 Service_Service 介绍 | 学习笔记
|
IDE Java 开发工具
Service 层和 Dao 的接口是不是多此一举?
今天我们要探讨的问题是:Service 层和 Dao 的接口是不是多此一举? 现在结合我参与的项目以及阅读的一些项目源码来看。如果「项目中使用了像Spring这样的依赖注入框架,那可以不用接口」! 先来说说为什么使用了依赖注入框架以后,可以不使用接口!
216 0
|
Java 数据管理 数据库连接
JBPM学习(二):ProcessEngine与Service API
本文主要讲ProcessEngine与Service API
197 0
|
IDE Java 开发工具
Service 层需要实现接口吗?
前几天看技术交流群的话题,又刷到了「Service 层和 Dao 层真的有必要每个类都加上接口吗?」这个问题,之前简单回答了一波,给出的观点是「看情况」 现在结合我参与的项目以及阅读的一些项目源码来
使用C4C ABSL调用外部web service创建service request
使用C4C ABSL调用外部web service创建service request