Flowable常用方法

Flowable笔记

1. Flowable介绍

  • Flowable是一个使用Java编写的轻量级业务流程引擎。Flowable流程引擎可用于部署BPMN 2.0流程定义(用于定义流程的行业XML标准), 创建这些流程定义的流程实例,进行查询,访问运行中或历史的流程实例与相关数据,等等。这个章节将用一个可以在你自己的开发环境中使用的例子,逐步介绍各种概念与API。
  • Flowable可以十分灵活地加入你的应用/服务/构架。可以将JAR形式发布的Flowable库加入应用或服务,来嵌入引擎。 以JAR形式发布使Flowable可以轻易加入任何Java环境:Java SE;Tomcat、Jetty或Spring之类的servlet容器;JBoss或WebSphere之类的Java EE服务器,等等。 另外,也可以使用Flowable REST API进行HTTP调用。也有许多Flowable应用(Flowable Modeler, Flowable Admin, Flowable IDM 与 Flowable Task),提供了直接可用的UI示例,可以使用流程与任务。

2. 模块介绍

项目结构

  • flowable-idm:用户管理模块【用户的创建、访问权限的管理】
  • flowable-modeler:流程设计器【创建流程、新建应用程序和发布】
  • flowable-task:启动应用程序、查询代办任务

表结构

  • ACT_RE_*: RE表示repository(存储) RepositoryService接口操作的表。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
  • ACT_RU_*: RU表示runtime(15张表) 这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。flowable只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
  • ACT_ID_*: ID表示identity(组织机构-9张表)这些表包含标识的信息,如用户,用户组,等等。
  • ACT_HI_*: HI表示history(10张表) 就是这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。
  • ACT_GE_*: 普通数据(2张表)各种情况都使用的数据。
  • *_ DATABASECHANGELOG liuquibase的log表(4张表)
  • * _DATABASECHANGELOGLOCK liuquibase的log表(4张表)

2.1 人员组织

2.1.1 表结构
IDMODELTABLE_NAMEREAMARKS
7ACT_ID_BYTEARRAY二进制数据
10IdentityInfoEntityImplACT_ID_INFO人员信息详情
19GroupEntityImplACT_ID_GROUP分组
13MemberShipEntityImplACT_ID_MEMBERSHIP用户和分组中间信息表
25ACT_ID_PRIV权限
28ACT_ID_PRIV_MAPPING用户或者分组的权限信息中间表
4ACT_ID_PROPERTY属性
22ACT_ID_TOKEN系统登录日志
16UserEntityImplACT_ID_USER用户
2.1.2 构建IDM
  1. maven配置文件

      <properties>
            <java.version>1.8</java.version>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <slf4j.version>1.7.25</slf4j.version>
            <flowable.version>6.4.1</flowable.version>
            <druid.version>1.2.4</druid.version>
            <mysql.version>5.1.47</mysql.version>
        </properties>
    
        <dependencies>
            <!-- logging -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <!--flowAble-->
            <dependency>
                <groupId>org.flowable</groupId>
                <artifactId>flowable-spring</artifactId>
                <version>${flowable.version}</version>
            </dependency>
            <dependency>
                <groupId>org.flowable</groupId>
                <artifactId>flowable-engine</artifactId>
                <version>${flowable.version}</version>
            </dependency>
            <!--druid-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- mysql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.2</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
  2. IDM引擎配置

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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">
    
        <!-- idm引擎配置 -->
        <bean id="idmEngineConfiguration" class="org.flowable.idm.engine.IdmEngineConfiguration">
            <property name="dataSource" ref="dataSource"></property>
            <property name="databaseSchemaUpdate" value="true"></property>
        </bean>
    
        <!--数据源-->
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
            <property name="url" value="jdbc:mysql://127.0.0.1:3306/flowable?characterEncoding=UTF-8"></property>
            <property name="username" value="root"></property>
            <property name="password" value="root"></property>
        </bean>
    </beans>
    
  3. 常用API

    package com.flowable;
    
    import org.flowable.common.engine.api.management.TableMetaData;
    import org.flowable.idm.api.*;
    import org.flowable.idm.engine.IdmEngine;
    import org.flowable.idm.engine.IdmEngineConfiguration;
    import org.flowable.idm.engine.impl.persistence.entity.GroupEntityImpl;
    import org.flowable.idm.engine.impl.persistence.entity.UserEntityImpl;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.io.InputStream;
    import java.util.List;
    import java.util.Map;
    
    
    /**
     * @author Laisheng
     * @version 1.0
     * @date 2021-07-21
     * @className FlowAbleIdmTest
     * @description flowable-idm-api-test
     **/
    public class FlowAbleIdmTest {
    
        private IdmEngine idmEngine;
        private IdmIdentityService idmIdentityService;
        private IdmEngineConfiguration configuration;
        private IdmManagementService managementService;
        private String idmName;
    
        /**
         * 初始化IDM引擎配置
         */
        @Before
        public void initFlowAbleIdm(){
            InputStream stream = FlowAbleIdmTest.class.getClassLoader().getResourceAsStream("flowable.idm.cfg.xml");
            idmEngine = IdmEngineConfiguration.createIdmEngineConfigurationFromInputStream(stream).buildIdmEngine();
            idmIdentityService = idmEngine.getIdmIdentityService();
            configuration = idmEngine.getIdmEngineConfiguration();
            managementService = idmEngine.getIdmManagementService();
            idmName = idmEngine.getName();
            System.out.println("引擎名称:"+ idmName);
        }
    
        /**
         * 添加用户
         */
        @Test
        public void addUserTest(){
            UserEntityImpl userEntity = new UserEntityImpl();
            userEntity.setEmail("test0006@qq.com");
            userEntity.setId("test0006");
            userEntity.setPassword("test");
            userEntity.setRevision(0);
            idmIdentityService.saveUser(userEntity);
        }
    
        /**
         * 添加分组
         */
        @Test
        public void addGroupTest(){
            GroupEntityImpl groupEntity = new GroupEntityImpl();
            groupEntity.setId("yanfabu");
            groupEntity.setName("研发部");
            groupEntity.setRevision(0);
            idmIdentityService.saveGroup(groupEntity);
        }
    
        /**
         * 用户分配组
         */
        @Test
        public void addUserForGroup(){
            String userId ="test0006",groupId="yanfabu";
            idmIdentityService.createMembership(userId,groupId);
        }
    
        /**
         * 用户和分组分配权限
         */
        @Test
        public void addPriVile(){
            String privilegeName = "测试权限",priVileId = "8e5de021-e934-11eb-9f6e-f8e4e3d3dff7",userId = "test0006",groupId = "yanfabu";
            idmIdentityService.createPrivilege(privilegeName);
            idmIdentityService.addUserPrivilegeMapping(priVileId,userId);
            idmIdentityService.addGroupPrivilegeMapping(priVileId,groupId);
        }
    
        /**
         * 查询用户
         */
        @Test
        public void findUser(){
            UserQuery userQuery = idmIdentityService.createUserQuery();
            List<User> users = userQuery.list();
            users.forEach(user -> System.out.println(user.getId()));
        }
    
        /**
         * 查询分组
         */
        @Test
        public void findGroup(){
            GroupQuery groupQuery = idmIdentityService.createGroupQuery();
            List<Group> groups = groupQuery.list();
            groups.forEach(Group -> System.out.println(Group.getId()));
        }
    
        /**
         * 查询权限
         */
        @Test
        public void findPriVile(){
            PrivilegeQuery privilegeQuery = idmIdentityService.createPrivilegeQuery();
            List<Privilege> privileges = privilegeQuery.list();
            privileges.forEach(privilege -> System.out.println(privilege.getId()+":"+privilege.getName()));
            String priVileId = "8e5de021-e934-11eb-9f6e-f8e4e3d3dff7";
            // 根据权限查询用户
            List<User> usersWithPrivilege = idmIdentityService.getUsersWithPrivilege(priVileId);
            usersWithPrivilege.forEach(user -> System.out.println(user.getId()));
            // 根据权限查询分组
            List<Group> groupsWithPrivilege = idmIdentityService.getGroupsWithPrivilege(priVileId);
            groupsWithPrivilege.forEach(group -> System.out.println(group.getId()));
        }
    
        /**
         * 获取table相关数据
         */
        @Test
        public void findManagementTable(){
            // 获取表名和数据条数
            Map<String, Long> tableCount = managementService.getTableCount();
            tableCount.forEach((k,v)-> System.out.println(k+" : "+v));
            // 根据class获取表面
            String tableName = managementService.getTableName(User.class);
            System.out.println(tableName);
            // 获取配置信息
            Map<String, String> properties = managementService.getProperties();
            properties.forEach((k,v)-> System.out.println(k+" : "+v));
            // 获取数据库表的元数据信息
            TableMetaData tableMetaData = managementService.getTableMetaData("ACT_ID_USER");
            System.out.println(tableMetaData.getColumnNames());
            System.out.println(tableMetaData.getColumnTypes());
        }
    }
    

2.2 引擎

2.2.1 引擎服务类信息
  • AbstractEngineConfiguration:引擎顶级父类
    • CmmnEngineConfiguration
    • IdmEngineConfiguration
    • AppEngineConfiguration
    • ProcessEngineConfiguration
  • ProcessEngines:流程引擎管理类
  • ProcessEngine:流程引擎类
  • ProcessEngineImpl:流程引擎实现类
  • ProcessEngineConfiguration:流程引擎配置类
  • ProcessEngineConfigurationImpl:流程引擎配置实现类
  • EngineInfo:流程引擎信息类
2.2.2 常用服务类信息
beanNameremarks
ProcessEngine流程引擎类
RepositoryService流程定义
DynamicBpmnService动态bpmn服务
HistoryService历史
FormService表单
TaskService任务
IdentityService用户
ManagementService执行cmd以及job
RuntimeService流程实例
ProcessEngineConfiguration流程引擎配置
2.2.3 引擎初始化步骤和常用API

初始化流程引擎实例化以下服务对象

// 初始化流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

通过flowable **flowable.cfg.xml **配置文件初始化引擎

<?xml version="1.0" encoding="UTF-8"?>
<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="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/flowable?characterEncoding=UTF-8"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
	<!-- 引擎 -->
    <bean id="processEngineConfiguration" class="org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="databaseType" value="mysql"></property>
        <property name="databaseSchemaUpdate" value="true"/>
        <property name="dataSource" ref="dataSource"></property>
        <!-- 监听 -->
        <property name="processEngineLifecycleListener">
            <bean class="com.flowable.listener.FlowAbleProcessEngineLifecycleListener"></bean>
        </property>
    </bean>
</beans>

初始化引擎步骤

/**
 * 初始化引擎步骤
 **/
private static ProcessEngine buildProcessEngine(URL resource) {
        InputStream inputStream = null;
        try {
            inputStream = resource.openStream();
            // 根据flowable.cfg.xml配置文件实例化流程引擎配置类
            ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream);
            // 实例化引擎类
            return processEngineConfiguration.buildProcessEngine();
        } catch (IOException e) {
            throw new FlowableIllegalArgumentException("couldn't open resource stream: " + e.getMessage(), e);
        } finally {
            IoUtil.closeSilently(inputStream);
        }
}

@Override
public ProcessEngine buildProcessEngine() {
    // 初始化引擎配置类中的属性
    init();
    // 实例化流程引擎实现类
    ProcessEngineImpl processEngine = new ProcessEngineImpl(this);
    // 《Flowable 5》引擎的触发构建
    if (flowable5CompatibilityEnabled && flowable5CompatibilityHandler != null) {
        commandExecutor.execute(new Command<Void>() {
            @Override
            public Void execute(CommandContext commandContext) {
                flowable5CompatibilityHandler.getRawProcessEngine();
                return null;
            }
        });
    }
    // 校验flowable流程实例数量
    postProcessEngineInitialisation();
    return processEngine;
}

创建引擎的五种方式

public static ProcessEngineConfiguration createProcessEngineConfigurationFromResourceDefault() {
        return createProcessEngineConfigurationFromResource("flowable.cfg.xml", "processEngineConfiguration");
    }

    public static ProcessEngineConfiguration createProcessEngineConfigurationFromResource(String resource) {
        return createProcessEngineConfigurationFromResource(resource, "processEngineConfiguration");
    }

    public static ProcessEngineConfiguration createProcessEngineConfigurationFromResource(String resource, String beanName) {
        return (ProcessEngineConfiguration) BeansConfigurationHelper.parseEngineConfigurationFromResource(resource, beanName);
    }

    public static ProcessEngineConfiguration createProcessEngineConfigurationFromInputStream(InputStream inputStream) {
        return createProcessEngineConfigurationFromInputStream(inputStream, "processEngineConfiguration");
    }

    public static ProcessEngineConfiguration createProcessEngineConfigurationFromInputStream(InputStream inputStream, String beanName) {
        return (ProcessEngineConfiguration) BeansConfigurationHelper.parseEngineConfigurationFromInputStream(inputStream, beanName);
    }

    public static ProcessEngineConfiguration createStandaloneProcessEngineConfiguration() {
        return new StandaloneProcessEngineConfiguration();
    }

    public static ProcessEngineConfiguration createStandaloneInMemProcessEngineConfiguration() {
        return new StandaloneInMemProcessEngineConfiguration();
    }

spring风格初始化引擎

<?xml version="1.0" encoding="UTF-8"?>
<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="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
        <property name="driverClass" value="org.h2.Driver"/>
        <property name="url" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>
<!--事务管理-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
<!--SpringProcessEngineConfiguration引擎配置-->
    <bean id="processEngineConfiguration" class="org.flowable.spring.SpringProcessEngineConfiguration">
        <property name="dataSource" ref="dataSource"/>
        <property name="transactionManager" ref="transactionManager"/>
        <property name="databaseSchemaUpdate" value="true"/>
        <property name="mailServerHost" value="localhost"/>
        <property name="mailServerPort" value="5025"/>
        <property name="asyncExecutorActivate" value="false" />
    </bean>
	<!--流程引擎-->
    <bean id="processEngine" class="org.flowable.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration"/>
    </bean>
	<!--流程定义-->
    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
    <!--流程实例-->
    <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
    <!--任务-->
    <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService"/>
   	<!--历史-->
    <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>
    <!--表单-->
    <bean id="formService" factory-bean="processEngine" factory-method="getFormService"/>
   	<!--执行cmd以及job-->
    <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService"/>

</beans>
 /**
     * Initializes all process engines that can be found on the classpath for resources <code>flowable.cfg.xml</code> (plain Flowable style configuration) and for resources
     * <code>flowable-context.xml</code> (Spring style configuration).
     */
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");
        } 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);
        }

        try {
            resources = classLoader.getResources("flowable-context.xml");
        } 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);
        }

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

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

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

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

/**
 * 通过spring方式加载ProcessEngineFactoryBean 
 */
public class SpringConfigurationHelper {
    private static final Logger LOGGER = LoggerFactory.getLogger(SpringConfigurationHelper.class);
    public static ProcessEngine buildProcessEngine(URL resource) {
        LOGGER.debug("==== BUILDING SPRING APPLICATION CONTEXT AND PROCESS ENGINE =========================================");
        try (GenericXmlApplicationContext applicationContext = new GenericXmlApplicationContext(new UrlResource(resource))) {
            Map<String, ProcessEngine> beansOfType = applicationContext.getBeansOfType(ProcessEngine.class);
            if ((beansOfType == null) || beansOfType.isEmpty()) {
                throw new FlowableException("no " + ProcessEngine.class.getName() + " defined in the application context " + resource.toString());
            }
            ProcessEngine processEngine = beansOfType.values().iterator().next();
            LOGGER.debug("==== SPRING PROCESS ENGINE CREATED ==================================================================");
            return processEngine;
        }
    }
}

2.3 流程定义

2.3.1 流程定义相关服务类
  • **RepositoryServiceImpl:**流程定义服务类
    • DeploymentBuilder:用来定义流程部署的相关参数

    • ProcessDefinitionQuery:用来构造查询流程定义相关参数

    • NativeProcessDefinitionQuery:用来构造本地SQL查询流程定义相关参数

    • DeploymentQuery:用来构造查询部署对象相关参数

2.3.2 表结构
MODELTABLE_NAMEREMARKS
DeploymentEntityImplact_re_deployment部署对象表
ProcessDefinitionEntityImplact_re_procdef流程定义表,key是相同的情况下,默认版本升级
ByteArrayEntityImplact_ge_bytearray资源文件表
PropertyEntityImplact_ge_property主键生成策略表/属性表
ModelEntityImplact_re_model模型信息表
ProcessDefinitionInfoEntityImplact_procdef_info流程定义动态改变信息表
2.3.3 常用API
package com.flowable.service;

import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.impl.util.IoUtil;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngines;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;

/**
 * @author Laisheng
 * @version 1.0
 * @date 2021-07-22
 * @className RepositoryServiceTest
 * @description 流程定义
 **/
public class RepositoryServiceTest {

    private ProcessEngine processEngine;

    private RepositoryService repositoryService;

    /**
     * 引擎相关配置
     */
    @Before
    public void processEngineTest() {
        processEngine = ProcessEngines.getDefaultProcessEngine();
        repositoryService = processEngine.getRepositoryService();
    }

    /**
     * 关闭
     */
    @After
    public void closeFlowEngine() {
        processEngine.close();
    }

    /**
     * 开始创建新部署
     */
    @Test
    public void createDeployment() {
        String deployString = IoUtil.readFileAsString("oneTaskProcess.bpmn20.xml");
        InputStream inputStream = RepositoryServiceTest.class.getClassLoader().getResourceAsStream("oneTaskProcess.bpmn20.xml");
        DeploymentBuilder deployment = repositoryService.createDeployment()
                .category("test category")
                .name("test name")
                //.addInputStream("oneTaskProcess.bpmn20.xml",inputStream);
                .addString("oneTaskProcess.bpmn20.xml",deployString);

        Deployment deploy = deployment.deploy();
        System.out.println(deploy);
    }

    /**
     * 流程定义查询
     */
    @Test
    public void findProcessDefinitionQuery(){
        // 流程定义
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery().latestVersion();
        processDefinitionQuery.list().forEach(processDefinition -> System.out.println(processDefinition.toString()));
        // 流程部署查询
        DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
        deploymentQuery.list().forEach(deployment -> System.out.print(deployment.getId()+"\t"));
        // 流程部署本地SQL查询
        NativeProcessDefinitionQuery nativeProcessDefinitionQuery = repositoryService.createNativeProcessDefinitionQuery();
        NativeProcessDefinitionQuery sql = nativeProcessDefinitionQuery.sql("select * from act_re_procdef");
        sql.list().forEach(processDefinition -> System.err.println(processDefinition.getId()));
        // 根据部署ID删除流程定义
        repositoryService.deleteDeployment("20001",true);
    }
}

2.4 流程实例

2.4.1 RuntimeService 流程执行服务类接口

RuntimeService核心功能:启动实例【定义部署好流程,启动该流程】、查询实例相关信息

ProcessInstanceBuilder:定义启动流程实例相关参数【RuntimeService的派生类】

启动实例的方式:

  • processDefinitionKey:流程定义的key
  • processDefinitionKey + 租户ID:流程定义的key和租户的ID
  • processDefinitionID:流程定义的ID
  • messageName:消息名称
  • messageName + 租户ID:消息的名称和租户的ID
2.4.2 概念:
  • 流程定义
    • 提前定义好流程相关信息,类似在java中定义的类,提前确定参数属性
  • 执行实例
    • 流程在运转过程中执行的任务环节和节点,就是对于的执行实例
    • 启动流程会先创建流程实例,然后在创建执行实例
    • 一个流程中,执行对象可以有多个,但是流程实例只能有一个
  • 流程实例
    • 流程定义的执行实例;好比请假审批,想请假就必须向所属领导进行申请
    • 流程实例中包含所有的环节和节点信息
  • 特别注意:流程实例本质上也是一个执行实例【是当前定义的流程中最大的执行实例】
2.4.3 流程执行的大致过程
  • 启动实例 -> 创建流程实例 -> 执行实例 -> 更新实例 -> 流程环节结束 -> 实例结束
2.4.4 表结构
  • 运行时流程数据表
MODELTABLE_NAMEREMARKS
ExecutionEntityImplact_ru_execution流程实例与分支执行表
TaskEntityImplact_ru_task用户任务表
IdentityLinkEntityImplact_ru_identitylink参与者相关信息表
JobEntityImplact_ru_job作业表
act_ru_history_job历史作业表
TimerJobEntityImplact_ru_timer_job定时器表
SuspendedJobEntityImplact_ru_suspended_job暂停作业表
DeadLetterJobEntityImplact_ru_deadletter_job死信表
VariableInstanceEntityImplact_ru_variable变量信息
EventSubscriptionEntityImplact_ru_event_subscr事件订阅表
  • 历史流程数据表
MODELTABLE_NAMEREMARKS
HistoricProcessInstanceEntityImplact_hi_procinst历史流程实例表
HistoricActivityInstanceEntityImplact_hi_actinst历史节点信息表
HistoricTaskInstanceEntityImplact_hi_taskinst历史任务表
HistoricVariableInstanceEntityImplact_hi_varinst历史变量
HistoricIdentityLinkEntityImplact_hi_identitylink历史参与者表
HistoricDetailEntityImplact_hi_detail历史的流程运行中的细节信息
AttachmentEntityImplact_hi_attachment附件表
CommentEntityImplact_hi_comment评论表
EventLogEntryEntityImplact_evt_log事件日志表
2.4.5 常用API
package com.flowable.service;

import org.flowable.engine.*;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.DeploymentQuery;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ExecutionQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * @author Laisheng
 * @version 1.0
 * @date 2021-07-27
 * @className RuntimeServiceTest
 * @description 流程实例单元测试
 **/
public class RuntimeServiceTest {

    private ProcessEngine processEngine;

    private RepositoryService repositoryService;

    private RuntimeService runtimeService;

    private TaskService taskService;

    /**
     * 引擎相关配置
     */
    @Before
    public void processEngineTest() {
        processEngine = ProcessEngines.getDefaultProcessEngine();
        repositoryService = processEngine.getRepositoryService();
        runtimeService = processEngine.getRuntimeService();
        taskService = processEngine.getTaskService();
    }

    /**
     * 关闭
     */
    @After
    public void closeFlowEngine() {
        processEngine.close();
    }

    /**
     * 获取定义的流程
     */
    @Test
    public void findDeployment() {
        DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
        List<Deployment> deployments = deploymentQuery.list();
        deployments.forEach(deployment -> System.out.println(deployment.toString()));
    }

    /**
     * 启动流程实例
     * 定义测试流程:DeploymentEntity[id=30001, name=请假流程, key=Expense]
     */
    @Test
    public void startDeployment() {
        String businessKey = "dataObject";
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(businessKey);
        System.out.println("流程实例的流程定义id:" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例的流程定义键:" + processInstance.getProcessDefinitionKey());
        System.out.println("实例ID:" + processInstance.getId());
        System.out.println("返回当前执行所在的活动的id:" + processInstance.getActivityId());
    }

    /**
     * 个人任务查询
     */
    @Test
    public void findRuntimeService() {
        TaskQuery taskQuery = taskService.createTaskQuery();
        List<Task> list = taskQuery.taskAssignee("张三")
                .processDefinitionKey("Expense")
                .list();
        list.forEach(task -> System.out.println(task.getId() + ":" + task.getName() + ":" + task.getTaskDefinitionKey()));

    }

    /**
     * 执行任务
     */
    @Test
    public void handlerTask() {
        // 当任务成功执行时调用
        taskService.complete("22501");
    }

    /**
     * 查看流程状态,判断流程正在执行还是结束,有数据的情况正在执行,没有数据表示已经结束
     */
    @Test
    public void queryProcessInstance() {
        ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
        ProcessInstance processInstance = processInstanceQuery.processInstanceId("2501").singleResult();
        System.out.println(Objects.nonNull(processInstance) ? "执行" : "结束");
    }

    /**
     * 查询执行实例
     */
    @Test
    public void queryExecuteInstance() {
        ExecutionQuery executionQuery = runtimeService.createExecutionQuery();
        List<Execution> list = executionQuery.list();
        list.forEach(execution -> System.out.println(execution.getId()+": "+execution.getActivityId()));
    }


    /**
     * 判断当前定义的流程是否被挂起
     */
    @Test
    public void isProcessDefinitionSuspended(){
        boolean processDefinitionSuspended = repositoryService.isProcessDefinitionSuspended("dataObject:2:17504");
        System.out.println(processDefinitionSuspended);
    }


    /**
     * 挂起定义的流程
     * 流程定义表状态为2时,表示流程被挂起
     */
    @Test
    public void suspendProcessDefinitionById(){
        repositoryService.suspendProcessDefinitionById("dataObject:2:17504");
    }

    @Test
    public void startProcessDefinitionById(){
        ProcessInstance processInstance = runtimeService.startProcessInstanceById("dataObject:2:17504");
    }

    /**
     * 激活定义的流程
     */
    @Test
    public void activateProcessDefinitionById(){
        repositoryService.activateProcessDefinitionById("dataObject:2:17504");
    }

    /**
     * 挂起流程实例
     */
    @Test
    public void suspendProcessInstanceById(){
        runtimeService.suspendProcessInstanceById("22501");
    }
    
    /**
     * 激活流程实例
     */
    @Test
    public void activateProcessInstanceById(){
        runtimeService.activateProcessInstanceById("22501");
    }
}

2.5 流程节点

2.6 流程变量

2.7 历史数据

2.8 定时任务

2.9 表单

2.10 流程图

flowable操作手册

flowable-version: 6.4.2

1. idm模块

在这里插入图片描述

1.1 创建用户

在这里插入图片描述

1.2 创建分组

在这里插入图片描述

1.3 分配权限

在这里插入图片描述

2. modeler模块

在这里插入图片描述

2.1 绘制流程图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 绘制表单

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 配置条件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4 分配节点用户

在这里插入图片描述

2.5 配置应用程序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.6 发布应用程序

在这里插入图片描述

3. task模块

3.1 查询任务

在这里插入图片描述

3.2 启动流程

在这里插入图片描述

3.3 完成任务

在这里插入图片描述

4. admin模块

4.1 查看引擎相关配置

在这里插入图片描述

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值