activiti学习笔记(一)hello world

工作中需要使用到activiti工作流引擎,于是在业余时间学习activiti相关的内容,今天分享一个使用activiti来实现的请假流程,其中涉及分支条件的判断和表单的填写,下面就来分享下这个简单程序的内容。

环境搭建

使用maven来搭建工程,需要依赖如下:

<dependencies>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>6.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.197</version>
        </dependency>
    </dependencies>

使用h2数据库的原因是activiti的默认数据库就是H2,方便简单测试,此处加上h2的驱动。

流程图设计

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" 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:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1536107421286" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="second_approve" isClosed="false" isExecutable="true" name="二级审批" processType="None">
    <startEvent id="startEvent" name="开始"/>
    <userTask activiti:exclusive="true" id="submitForm" name="填写审批信息">
      <extensionElements>
        <activiti:formProperty id="message" name="申请信息" required="true" type="string"/>
        <activiti:formProperty id="name" name="申请人姓名" required="true" type="string"/>
        <activiti:formProperty datePattern="yyyy-MM-dd" id="submitTime" name="提交时间" required="true" type="date"/>
        <activiti:formProperty id="submitType" name="提交类型" required="true" type="string"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow1" sourceRef="startEvent" targetRef="submitForm"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="decideSubmit" name="提交或取消"/>
    <sequenceFlow id="flow2" sourceRef="submitForm" targetRef="decideSubmit"/>
    <userTask activiti:exclusive="true" id="tl_approve" name="主管审批">
      <extensionElements>
        <activiti:formProperty id="tlApprove" name="主管审批结果" type="string"/>
        <activiti:formProperty id="tlMessage" name="主管备注" required="true" type="string"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow3" sourceRef="decideSubmit" targetRef="tl_approve">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${submitType == "y" || submitType == "Y"}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway gatewayDirection="Unspecified" id="decideTLApprove" name="主管审批校验"/>
    <sequenceFlow id="flow4" sourceRef="tl_approve" targetRef="decideTLApprove"/>
    <userTask activiti:exclusive="true" id="hr_approve" name="人事审批">
      <extensionElements>
        <activiti:formProperty id="hrApprove" name="人事审批结果" required="true" type="string"/>
        <activiti:formProperty id="hrMessage" name="人事审批备注" required="true" type="string"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow5" sourceRef="decideTLApprove" targetRef="hr_approve">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${tlApprove == "y" || tlApprove == "Y"}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="endEventCancel" name="取消"/>
    <sequenceFlow id="flow7" sourceRef="decideSubmit" targetRef="endEventCancel">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${submitType == "n" || submitType == "N"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow8" sourceRef="decideTLApprove" targetRef="submitForm">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${tlApprove == "n" || tlApprove == "N"}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway gatewayDirection="Unspecified" id="decideHRApprove" name="人事审批校验"/>
    <sequenceFlow id="flow9" sourceRef="hr_approve" targetRef="decideHRApprove"/>
    <endEvent id="endEvent" name="结束"/>
    <sequenceFlow id="flow10" sourceRef="decideHRApprove" targetRef="endEvent">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApprove == "y" || hrApprove == "Y"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow11" sourceRef="decideHRApprove" targetRef="submitForm">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrApprove == "n" || hrApprove == "N"}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="second_approve">
      <bpmndi:BPMNShape bpmnElement="startEvent" id="Shape-startEvent">
        <omgdc:Bounds height="32.0" width="32.0" x="-17.5" y="-17.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="submitForm" id="Shape-submitForm">
        <omgdc:Bounds height="55.0" width="105.0" x="-52.5" y="-27.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="decideSubmit" id="Shape-decideSubmit" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="-20.0" y="-20.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="tl_approve" id="Shape-tl_approve">
        <omgdc:Bounds height="55.0" width="105.0" x="-52.5" y="-27.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="decideTLApprove" id="Shape-decideTLApprove" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="-20.0" y="-20.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="hr_approve" id="Shape-hr_approve">
        <omgdc:Bounds height="55.0" width="105.0" x="-52.5" y="-27.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endEventCancel" id="Shape-endEventCancel">
        <omgdc:Bounds height="32.0" width="32.0" x="-17.5" y="-17.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="decideHRApprove" id="Shape-decideHRApprove" isMarkerVisible="false">
        <omgdc:Bounds height="32.0" width="32.0" x="-20.0" y="-20.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endEvent" id="Shape-endEvent">
        <omgdc:Bounds height="32.0" width="32.0" x="-17.5" y="-17.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1" sourceElement="startEvent" targetElement="submitForm">
        <omgdi:waypoint x="14.992185591719476" y="-1.5"/>
        <omgdi:waypoint x="-1.5" y="-27.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2" sourceElement="submitForm" targetElement="decideSubmit">
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3" sourceElement="decideSubmit" targetElement="tl_approve">
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4" sourceElement="tl_approve" targetElement="decideTLApprove">
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5" sourceElement="decideTLApprove" targetElement="hr_approve">
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7" sourceElement="decideSubmit" targetElement="endEventCancel">
        <omgdi:waypoint x="12.0" y="-4.0"/>
        <omgdi:waypoint x="480.0" y="427.0"/>
        <omgdi:waypoint x="14.992185591719476" y="-1.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10" sourceElement="decideHRApprove" targetElement="endEvent">
        <omgdi:waypoint x="-4.0" y="-4.0"/>
        <omgdi:waypoint x="14.904008928568928" y="-2.75"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8" sourceElement="decideTLApprove" targetElement="submitForm">
        <omgdi:waypoint x="12.0" y="-4.0"/>
        <omgdi:waypoint x="714.0" y="466.0"/>
        <omgdi:waypoint x="362.0" y="466.0"/>
        <omgdi:waypoint x="53.0" y="0.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11" sourceElement="decideHRApprove" targetElement="submitForm">
        <omgdi:waypoint x="12.0" y="-4.0"/>
        <omgdi:waypoint x="997.0" y="290.0"/>
        <omgdi:waypoint x="410.0" y="290.0"/>
        <omgdi:waypoint x="53.0" y="0.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9" sourceElement="hr_approve" targetElement="decideHRApprove">
        <omgdi:waypoint x="-4.0" y="-27.0"/>
        <omgdi:waypoint x="-4.0" y="12.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="-1.0" width="-1.0" x="-1.0" y="-1.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

程序实现

这里使用main方法+命令行交互的方法来实现流程流转,main方法中的内容如下:

        logger.info("启动程序");

        // 创建流程引擎
        ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
        ProcessEngine processEngine = cfg.buildProcessEngine();
        String name = processEngine.getName();
        String version = ProcessEngine.VERSION;

        logger.info("流程引擎名称:{},版本:{}",name,version);

        // 部署流程定义文件
        RepositoryService repositoryService = processEngine.getRepositoryService();
        DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
        deploymentBuilder.addClasspathResource("second_approve.bpmn20.xml");
        Deployment deployment = deploymentBuilder.deploy();
        String deploymentId = deployment.getId();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().
                deploymentId(deploymentId).singleResult();

        logger.info("流程文件:{},流程定义id:{}",processDefinition.getName(),processDefinition.getId());

        // 启动流程
        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
        logger.info("流程实例id为:{}",processInstance.getId());

        // 处理任务
        Scanner scanner = new Scanner(System.in);
        while (processInstance != null && !processInstance.isEnded()){

            TaskService taskService = processEngine.getTaskService();
            List<Task> taskList = taskService.createTaskQuery().list();

            for(Task task : taskList){
                logger.info("待处理任务:{}",task.getName());
                FormService formService = processEngine.getFormService();
                TaskFormData taskFormData = formService.getTaskFormData(task.getId());
                List<FormProperty> formPropertyList = taskFormData.getFormProperties();
                Map<String,Object> variables = new HashMap<String,Object>();
                for(FormProperty formProperty : formPropertyList){
                    String line = null;
                    if(StringFormType.class.isInstance(formProperty.getType())){
                        logger.info("请输入{}:",formProperty.getName());
                        line = scanner.nextLine();
                        variables.put(formProperty.getId(),line);
                    } else if(DateFormType.class.isInstance(formProperty.getType())){
                        logger.info("请输入{}:(格式:yyyy-MM-dd)",formProperty.getName());
                        line = scanner.nextLine();
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                        Date date = new Date();
                        try {
                            date = dateFormat.parse(line);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        variables.put(formProperty.getId(),date);
                    }
                    logger.info("您输入的内容是:{}",line);
                }

                taskService.complete(task.getId(),variables);
            }
            logger.info("待处理任务数量有{}个",taskList.size());
        }

        logger.info("结束程序");

上述首先创建流程引擎配置类,接着使用配置类创建流程引擎,然后使用流程引擎获得各个service,通过这些service来实现流程部署,创建流程实例,执行每个节点的任务直到流程结束。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容