基于flowable6.5的第一个demo

摘要:
由于工作需要,我现在正在学习Flowable工作流。在这里,我们将向您展示您学习并通过测试的演示。我希望这对初学者有帮助。至于什么是工作流以及可流动和活动之间的区别,你可以自己百度。我在这里不再重复。直接进入演示:1.环境设置:jdk1.8+maven+eclipse以创建标准maven项目。项目框架截图如下:2.添加一个依赖项:pom。xml˂!

  因工作需要,本人现在在学习Flowable工作流。此处将自己学习和测试通过的demo展示给大家,希望对同为初学者的你有所帮助。

  对于什么是工作流,flowable和activiti的区别,各位可自行百度,此处不再赘述。

  直接上demo:

  1、环境搭建:jdk1.8+maven+eclipse

 创建标准的maven项目,项目框架截图如下:

 基于flowable6.5的第一个demo第1张

  2、添加相关依赖:pom.xml

<!-- https://mvnrepository.com/artifact/org.flowable/flowable-engine -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-engine</artifactId>
<version>6.5.0</version>
</dependency>

<dependency>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
<version>4.12</version>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.10</version>
<scope>compile</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>

<!-- 使用h2数据库,方便测试-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
</dependency>

  3、使用flowable插件创建mywork.bpmn文件(因篇幅问题,只贴关键代码),flowable插件安装请自行百度

  mywork.png如下:

基于flowable6.5的第一个demo第2张

  mywork.bpmn:

<process id="mywork" name="二级审批流程" isExecutable="true">
    <startEvent id="startEvent" name="开始"></startEvent>
    <userTask id="userDev" name="申请审批流程">
      <extensionElements>
        <activiti:formProperty id="message" name="申请信息" type="string" required="true"></activiti:formProperty>
        <activiti:formProperty id="name" name="申请人" type="string" required="true"></activiti:formProperty>
        <activiti:formProperty id="submitTime" name="提交时间" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty>
        <activiti:formProperty id="submitType" name="确认申请" type="string" required="true"></activiti:formProperty>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow1" sourceRef="startEvent" targetRef="userDev"></sequenceFlow>
    <exclusiveGateway id="Dev_exclusivegateway" name="确认提交"></exclusiveGateway>
    <sequenceFlow id="flow2" sourceRef="userDev" targetRef="Dev_exclusivegateway"></sequenceFlow>
    <userTask id="userTL" name="主管审批">
      <extensionElements>
        <activiti:formProperty id="TLApprove" name="主管审批结果" type="string" required="true"></activiti:formProperty>
        <activiti:formProperty id="TLMessage" name="主管备注" type="string" required="true"></activiti:formProperty>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow3" sourceRef="Dev_exclusivegateway" targetRef="userTL">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${submitType == "y" || submitType =="Y"}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endEvent" name="结束"></endEvent>
    <exclusiveGateway id="TL_exclusivegateway" name="主管审批结果"></exclusiveGateway>
    <sequenceFlow id="flow8" sourceRef="userTL" targetRef="TL_exclusivegateway"></sequenceFlow>
    <userTask id="userHR" name="人事审批">
      <extensionElements>
        <activiti:formProperty id="HRApprove" name="人事审批结果" type="string" required="true"></activiti:formProperty>
        <activiti:formProperty id="HRMessage" name="人事审批备注" type="string" required="true"></activiti:formProperty>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow9" sourceRef="TL_exclusivegateway" targetRef="userHR">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${TLApprove == "y" || TLApprove =="Y"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow11" sourceRef="TL_exclusivegateway" targetRef="userDev">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${TLApprove == "N" || TLApprove =="n"}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="HR_exclusivegateway" name="人事审批结果"></exclusiveGateway>
    <sequenceFlow id="flow12" sourceRef="userHR" targetRef="HR_exclusivegateway"></sequenceFlow>
    <endEvent id="endEvent1" name="取消"></endEvent>
    <sequenceFlow id="flow13" sourceRef="HR_exclusivegateway" targetRef="endEvent1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${HRApprove == "y" || HRApprove =="Y"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow14" sourceRef="HR_exclusivegateway" targetRef="userDev">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${HRApprove == "n" || HRApprove =="N"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow15" sourceRef="Dev_exclusivegateway" targetRef="endEvent1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${submitType == "n" || submitType =="N"}]]></conditionExpression>
    </sequenceFlow>
</process>

  4、创建主运行类:DemoMain.java

package com.lx.activiti.helloworld;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;


import org.flowable.engine.FormService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.form.FormProperty;
import org.flowable.engine.form.TaskFormData;
import org.flowable.engine.impl.form.DateFormType;
import org.flowable.engine.impl.form.StringFormType;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;

/**
 * 启动类
 * @author 
 *
 */
public class DemoMain {
    private static final Logger logger = LoggerFactory.getLogger(DemoMain.class);
    
    public static void main(String[] args) throws ParseException {
        logger.info("启动程序");
        //抽取各步骤作为方法调用
        //1. 创建流程引擎
        ProcessEngine processEngine = getProcessEngine();
        
        //2. 部署流程文件
        ProcessDefinition processDefinition = getDeployment(processEngine);
        
        //3. 启动运行流程
        ProcessInstance processInstance =getProcessInstance(processEngine, processDefinition);
        
        //4. 处理流程任务
        //控制台输入
        Scanner scanner = new Scanner(System.in);
        //判断,当流程实例不为空,且流程没有结束时
        while (processInstance!=null && !processInstance.isEnded()) {
            //获取任务服务组件
            TaskService taskService = processEngine.getTaskService();
            //创建任务查询,将结果放入list集合中
            List<Task> list = taskService.createTaskQuery().list();
            logger.info("待处理任务数量: [{}]",list.size());
            //遍历list集合
            for (Task task : list) {
                logger.info("待处理任务: [{}]",task.getName());
                //获取表单服务组件
                FormService formService = processEngine.getFormService();
                //获取表单内容的集合formProperties
                TaskFormData taskFormData = formService.getTaskFormData(task.getId());
                List<FormProperty> formProperties = taskFormData.getFormProperties();
                
                HashMap<String, Object> variables = Maps.newHashMap();
                String line = null;
                //遍历formProperties
                for (FormProperty property : formProperties) {
                    //判断,如果表单中定义的是字符串类型变量,则按该格式输入
                    if (StringFormType.class.isInstance(property.getType())) {
                        logger.info("请输入 {} ?",property.getName());
                        line = scanner.nextLine();
                        variables.put(property.getId(), line);
                        
                    //判断,如果表单中定义的是日期类型变量,按日期格式输入
                    }else if(DateFormType.class.isInstance(property.getType())) {
                        logger.info("请输入 {} ? 格式 (yyyy-MM-dd)",property.getName());
                        line = scanner.nextLine();
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                        Date date = dateFormat.parse(line);
                        variables.put(property.getId(), date);
                    }else {
                        logger.info("类型暂不支持 {} ",property.getType());
                    }
                    logger.info("你输入的是[{}]",line);
                }
                taskService.complete(task.getId(),variables);
                
                processInstance = processEngine.getRuntimeService()
                                    .createProcessInstanceQuery()
                                    .processInstanceId(processInstance.getId())
                                    .singleResult();
            }
        }
        logger.info("结束程序");
    }

    /**
     * 3. 获取流程实例:ProcessInstance,启动运行流程
     * @param processEngine
     * @param processDefinition
     * @return ProcessInstance
     */
    public static ProcessInstance getProcessInstance(ProcessEngine processEngine, ProcessDefinition processDefinition) {
        //获取运行服务
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //传入流程定义文件id,调用startProcessInstanceById(),获取流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
        //获取流程部定义文件的key值
        logger.info("启动流程[ {}]",processInstance.getProcessDefinitionKey());
        return processInstance;
    }

    /**
     * 2 .  获取流程定义文件:ProcessDefinition , 部署流程
     * @param processEngine
     * @return ProcessDefinition
     */
    public static ProcessDefinition getDeployment(ProcessEngine processEngine) {
        //通过引擎获取仓储服务
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //通过仓储服务链式调用,部署流程
        Deployment deploy = repositoryService.createDeployment()//得到流程部署
                                .addClasspathResource("diagrams/mywork.bpmn")//加载资源
                                .deploy();//部署流程
        String deployId = deploy.getId();
        //获取流程定义文件:processDefinition
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()//创建流程定义文件查询
                                                .deploymentId(deployId)//传入流程部署ID
                                                .singleResult();//根据查询条件;到数据库中查询唯一的数据记录,如果没有,则为空,如果有多条,则抛出异常
        logger.info("流程定义文件: [ {}] ,流程id: [{}]",processDefinition.getName(),processDefinition.getId());
        return processDefinition;
    }
     
    /**
     *  1. 创建流程引擎
     *  @return ProcessEngine
     */
    public static ProcessEngine getProcessEngine() {
        //获取流程配置文件
        ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
        //通过流程文件创建引擎
        ProcessEngine processEngine = cfg.buildProcessEngine();
        
        String name = processEngine.getName();
        String version = processEngine.VERSION;
        logger.info("流程引擎名称{},版本 [{}]}", name, version);
        return processEngine;
    }
}

  5、运行该类,截取部分测试结果如下图:

基于flowable6.5的第一个demo第3张

免责声明:文章转载自《基于flowable6.5的第一个demo》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇IC设计流程之实现篇——全定制设计Ubuntu下制作系统启动盘下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

springcloud Alibaba 微服务 flowable 工作流 自定义表单 vue.js前后分离

功能模块设计方案 1.代码生成器: [正反双向](单表、主表、明细表、树形表,快速开发利器)freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面、建表sql脚本、处理类、service等完整模块2.多数据源:(支持同时连接无数个数据库,可以不同的模块连接不同数的据库)支持N个数据源3.阿里数据库连接池druid,安全权限框架 shiro...

Java 三大主流 工作流 学习

之前听同学说,他们在用工作流,好奇,搜索了一下,查看和搜集了一番,摘抄入下:(来源于:gzRiven)  三大主流工作流引擎:Shark,osworkflow,jbpm!   Shark的靠山是Enhydra。Enhydra做过什么呢?多了!从j2ee应用服务器,到o/r mapping工具,到这个工作流引擎等等。   为什么Shark的持久层采用DODS...

关于工作流的模式

昨天发了几篇文章,被一些朋友说写的不认真,今天又写了几篇,请各位指点另承上,今晚随手写一篇[关于工作流的模式]的文章,没有什么技术性,无法归到技术栏里,就当随笔发吧-------------------------关于工作流的模式流模式(Sequential)1.适合一个比效机械化的流程2.在这种流程中,参与者处于一种被动的局面,他必须沿设定的路线一步一步...

Git-工作流介绍

一、为什么需要版本控制 1.概述 在软件开发过程,每天都会产生新的代码,代码合并的过程中可能会出现如下问题: 代码被覆盖或丢失 代码写的不理想希望还原之前的版本 希望知道与之前版本的差别 是谁修改了代码以及为什么修改 发版时希望分成不同的版本(测试版、发行版等) 因此,我们希望有一种机制,能够帮助我们: 可以随时回滚到之前的版本 协同开发时不会覆盖别...

eclipse安装activiti工作流插件

方式一:在有网络的情况下,安装流程设计器步骤如下: 1、点击eclipse上方工具栏的Help,选择Install New Software 2、弹出如下窗口,然后填写插件名称和安装地址 Name: Activiti BPMN 2.0 designer Location: http://activiti.org/designer/update/然后便是不...

Activiti如何替换已部署流程图

  首先交代下背景:我们有一个已经上线的activiti工作流系统,对于流程图的操作已经封装好部署,查看,删除的接口。此时客户提出要修改个别流程图里的节点名称。   我的第一个想法就是本地修改流程图bpmn文件,然后去客户端先调用删除接口删除旧流程图,然后调用部署接口添加修改后的流程图,然而事实上,因为系统已经上线,此时存在大量运行中的工作流数据,一旦执行...