springBoot集成Activiti5.0

一、工作流简介

1.什么是工作流?

简单的理解就是工作的流程,这里的流程指的是,完成一个企业中具体业务的一系列工作步骤,所有的步骤合在一起就是业务从开始到结束的流转过程。

从计算机系统的角度来讲,工作流系统表示:业务过程的部分和整体在计算机应用环境的自动化操作。

2.工作流的三大要素

①这个过程要做什么?

②经过多少个步骤?

③每个步骤是由谁来做,做什么,怎么做?

3.工作流系统的组成

流程定义工具:定义流程(画流程图)

表单定制工具:要提交的数据的表单的定制(可以用创建一个(html form)表单的表单形式替代)

工作流引擎: 工作流框架的核心,驱动着流程的流程,流程的数据共享,数据保存,流程的版本迭代....

管理监控工具:监控每一个流程的运转,管理每一个流程;

开发API:暴露给开发人员的api;

4.工作流需要解决的问题

    1)、流程的自动化流程控制

    2)、流程数据的保存(历史记录,历史数据的保存);

    3)、流程版本的更替;(维护流程的版本更替);

    4)、流程运行期间数据的共享等;

流程都具有一定的通用性;流程框架抽取流程的通用性,来统一管理和维护流程;

5.工作流的相关概念

①流程定义:(ProcessDefinition):

    流程的定义:流程图。表示一个流程的信息;一个流程定义(如:请假流程图)

②流程实例:(ProcessInstance):

    启动一个流程:称为创建一个流程的实例;无数个流程实例(如员工提交的请假单审批流程)

③流程变量:(ProcessVariable):

    流程运行提交的数据,共享的数据,等;

④任务:(Task)

    每一步需要完成的工作算是一个任务;(每一个流程运行都需要完成自己的流程规定的任务)

⑤开始、结束(Start 、End)

    每一个流程只有一个入口,无数的出口;(正常结束的出口,异常结束的出口等)

⑥网关(Gateway):

    流程的分支节点(判断节点);决定下一步走哪儿;

6.工作流产品

①JBPM

②OSWorkFlow

③Shark

④信雅达

⑤普元工作流

⑥Activiti5

7.ProcessEngine

ProcessEngine这个类是Activiti5的核心,所有的服务都需要通过ProcessEngine来创建,该类是线程安全的

Activiti5的持久化层采用的是Mybatis,这样移植性好,底层Spring+MyBatis;

Activiti5主要包括7个Service,这些Service都是通过ProcessEngine创建 

repositoryService(持久化服务)

runtimeService(运行时服务)

formService(表单服务)

identityService(身份信息)

taskService(任务服务)

historyService(历史信息)

managementService(管理定时任务)

8.Activiti5框架表结构

Activiti使用到的表都是ACT_开头的。

ACT_RE_*: ‘RE’表示repository(存储),RepositoryService接口所操作的表。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。

ACT_RU_*: ‘RU’表示runtime,运行时表-RuntimeService。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。Activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。

ACT_ID_*: ’ID’表示identity (组织机构),IdentityService接口所操作的表。用户记录,流程中使用到的用户和组。这些表包含标识的信息,如用户,用户组,等等。

ACT_HI_*: ’HI’表示history,历史数据表,HistoryService。就是这些表包含着流程执行的历史相关数据,如结束的流程实例,变量,任务,等等

ACT_GE_*: 全局通用数据及设置(general),各种情况都使用的数据。

act_ge_bytearray二进制数据表

act_ge_property属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录,

act_hi_actinst历史节点表

act_hi_attachment历史附件表

act_hi_comment历史意见表

act_hi_identitylink历史流程人员表

act_hi_detail历史详情表,提供历史变量的查询

act_hi_procinst历史流程实例表

act_hi_taskinst历史任务实例表

act_hi_varinst历史变量表

act_id_group用户组信息表

act_id_info用户扩展信息表

act_id_membership用户与用户组对应信息表

act_id_user用户信息表

act_re_deployment部署信息表

act_re_model流程设计模型部署表

act_re_procdef流程定义数据表

act_ru_event_subscr  throwEvent、catchEvent时间监听信息表

act_ru_execution运行时流程执行实例表

act_ru_identitylink运行时流程人员表,主要存储任务节点与参与者的相关信息

act_ru_job运行时定时任务数据表

act_ru_task运行时任务节点表

act_ru_variable运行时流程变量数据表

9.流程框架的标准

Business Process Management (BPM). 工作流管理系统

BPMN 2.0:Business Process Modeling Notation(中文:业务流程建模与标注)

OMG组织维护业务流程建模规范,以后所有流程框架绘制流程图都遵循这个规范;

二、流程框架的操作

1)、设计流程:画流程图;

2)、保存流程:给数据库中保存绘制的流程图(流程定义)

3)、导出流程:实际上绘制的流程是一个xml文件;bmpn规范;


<?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: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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">

  <process id="电话费报销" name="话费报销" isExecutable="true">

    <startEvent id="startevent1" name="Start"></startEvent>

    <userTask id="usertask1" name="部门经理审批"></userTask>

    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>

    <userTask id="usertask2" name="财务审批"></userTask>

    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>

    <userTask id="usertask3" name="总经理审批"></userTask>

    <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>

    <endEvent id="endevent1" name="End"></endEvent>

    <sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>

  </process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_电话费报销">

    <bpmndi:BPMNPlane bpmnElement="电话费报销" id="BPMNPlane_电话费报销">

      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">

        <omgdc:Bounds height="35.0" width="35.0" x="90.0" y="190.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">

        <omgdc:Bounds height="55.0" width="105.0" x="170.0" y="180.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">

        <omgdc:Bounds height="55.0" width="105.0" x="320.0" y="180.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">

        <omgdc:Bounds height="55.0" width="105.0" x="470.0" y="180.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">

        <omgdc:Bounds height="35.0" width="35.0" x="640.0" y="190.0"></omgdc:Bounds>

      </bpmndi:BPMNShape>

      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">

        <omgdi:waypoint x="125.0" y="207.0"></omgdi:waypoint>

        <omgdi:waypoint x="170.0" y="207.0"></omgdi:waypoint>

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">

        <omgdi:waypoint x="275.0" y="207.0"></omgdi:waypoint>

        <omgdi:waypoint x="320.0" y="207.0"></omgdi:waypoint>

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">

        <omgdi:waypoint x="425.0" y="207.0"></omgdi:waypoint>

        <omgdi:waypoint x="470.0" y="207.0"></omgdi:waypoint>

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">

        <omgdi:waypoint x="575.0" y="207.0"></omgdi:waypoint>

        <omgdi:waypoint x="640.0" y="207.0"></omgdi:waypoint>

      </bpmndi:BPMNEdge>

    </bpmndi:BPMNPlane>

  </bpmndi:BPMNDiagram>

</definitions>


<process></process>规定整个流程的流转;

<userTask ></userTask>规定用户任务;

<sequenceFlow></sequenceFlow>指定流转方向等...

4)、流程部署:实际就是把流程的定义信息(详情)保存到数据库; 给数据保存了流程定义

5)、启动流程:按照流程定义启动一次流程(流程实例)

6)、流程实例:流程框架控制自动流转到下一步;

7)、签收任务完成任务;完成以后,流程框架自动判断来到下一步

8)、查看历史流程    

三、Activiti5框架的几大组件

ProcessEngine :流程框架的核心 ;获取各大组件

activiti的七大组件:都是由流程引擎得到的;

以下为组件的获取方式:


ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

RuntimeService runtimeService = processEngine.getRuntimeService();

RepositoryService repositoryService = processEngine.getRepositoryService();

TaskService taskService = processEngine.getTaskService();

ManagementService managementService = processEngine.getManagementService();

IdentityService identityService = processEngine.getIdentityService();

HistoryService historyService = processEngine.getHistoryService();

FormService formService = processEngine.getFormService();


四、Activiti5的使用

1.导包(Activiti5默认使用的是h2的内存数据库,如果要使用mysql需要导入响应的驱动包)


        <dependency>

            <groupId>org.activiti</groupId>

            <artifactId>activiti-engine</artifactId>

            <version>5.22.0</version>

        </dependency>

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>5.1.42</version>

        </dependency>


2.编写流程框架配置文件(文件名:activiti.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">

    <!-- id必须是这个名称 -->

    <bean id="processEngineConfiguration"

        class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">

        <!--数据库的连接相关信息 -->

        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti" />

        <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />

        <property name="jdbcUsername" value="root" />

        <property name="jdbcPassword" value="123456" />

        <!-- 第一次启动创键数据库;以后升级数据库表结构 -->

        <property name="databaseSchemaUpdate" value="true" />

        <property name="jobExecutorActivate" value="false" />

        <property name="asyncExecutorEnabled" value="true" />

        <property name="asyncExecutorActivate" value="false" />

        

        <!--设置解决乱码问题  -->

        <property name="activityFontName" value="微软雅黑"></property>

        <property name="annotationFontName" value="微软雅黑"></property>

        <property name="labelFontName" value="微软雅黑"></property>

    </bean>

</beans>


3.获取流程引擎


    public static void main(String[] args) {

        //第一次获取流程引擎会创建很多表

        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

        System.out.println(engine.toString());

    }


第一次创建数据表时,此表中会有三条记录:

 



五、在eclipse中使用activiti5绘制流程图

1.安装绘制流程图的插件

 

2.部署流程(把流程定义(流程图)保存到数据库中);每次部署产生一个【流程定义】


    /**

     * 部署项目

     */

    @Test

    public void testDeployement() {

        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

        RepositoryService repositoryService = engine.getRepositoryService();

        Deployment deployment = repositoryService.createDeployment().addClasspathResource("话费报销流程.bpmn").deploy();

        System.out.println(deployment.getName());

        System.out.println(deployment.getId());

        System.out.println(deployment.getDeploymentTime());

    }


数据库效果:

act_ge_bytearray

 act_re_deployment

 act_re_procdef

 id_:流程定义的唯一id;流程引擎自动生成的;

rev_:数据库乐观锁机制

category_:分类

name_:流程定义的名字

key_:流程定义的key

version_:流程的版本号

deployment_id:那次部署产生的这个流程定义

resource_name_:流程定义的xml文件的名字;

dgrm_resource_name_:流程图的文件的名字;

其他等等的信息...

每一个流程图都有三个数据;

 同一个流程部署多次会产生多个版本;根据每一个流程图的id来区分;


3.查询流程部署信息


    /**

     * 查看数据库的流程部署信息

     */

    @Test

    public void testQueryPdeployment() {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RepositoryService repositoryService = processEngine.getRepositoryService();

        DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();

        List<Deployment> list = deploymentQuery.list();

        

        for (Deployment deployment : list) {

            

            System.out.println("部署流程id"+deployment.getId());

            System.out.println("部署流程名字"+deployment.getName());

            System.out.println("部署流程时间"+deployment.getDeploymentTime());

        }

    }


4.查询流程定义信息


    /**

     * 查看数据库的流程定义信息

     */

    @Test

    public void testQueryPdefintion(){

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RepositoryService repositoryService = processEngine.getRepositoryService();

        

        //获取数据库中所有的流程定义信息

        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();

        for (ProcessDefinition processDefinition : list) {

            System.out.println("部署的定义目录"+processDefinition.getCategory());

            System.out.println("部署的定义id"+processDefinition.getDeploymentId());

            System.out.println("部署的定义key"+processDefinition.getKey());

            System.out.println("部署的定义name"+processDefinition.getName());

            System.out.println("部署的定义版本"+processDefinition.getVersion());

            System.out.println("部署的定义流程图资源名"+processDefinition.getDiagramResourceName());

        }

        

        

    }


3.启动流程


    /**

     * 启动一个流程

     */

    @Test

    public void testStart() {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        RepositoryService repositoryService = processEngine.getRepositoryService();

        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

        ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionVersion(2).singleResult();

        

        RuntimeService runtimeService = processEngine.getRuntimeService();

        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());

        System.out.println("流程启动完成"+processInstance);

        

    }


4.查询任务,签收任务


   如果某个任务已经固定分配给某个人了,就不能再签了;如果要签,先要撤销签收unclaim; 

    /**

     * 查找当前流程运行的任务;

     */

    @Test

    public void testQueryTask() {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        TaskService taskService = processEngine.getTaskService();

        //查询当前任务

        Task task = taskService.createTaskQuery().singleResult();

        System.out.println(task);

        //签收任务

        taskService.claim(task.getId(), "admin");

        System.out.println("admin签收了"+task);

        

    }


5.执行任务,并自动流转到下一个流程


    /**

     * 执行任务

     */

    @Test

    public void testQueryTaskByUser() {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        TaskService taskService = processEngine.getTaskService();

        //获取admin要执行的任务

        Task task = taskService.createTaskQuery().taskAssignee("admin").singleResult();

        //执行任务

        taskService.complete(task.getId());

        System.out.println("admin完成任务"+task);

    }


6.查询任务的执行历史


    /**

     * 查询任务的执行历史

     */

    @Test

    public void testHistory() {

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //获取HistoryService进行历史任务的检索等操作

        HistoryService historyService = processEngine.getHistoryService();

        //查询所有已经完成的流程实例

        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processFinished().list();

        for (HistoricTaskInstance historicTaskInstance : list) {

            //查询那个历史任务是由谁在什么时间开始,在什么时间结束

            System.out.println(historicTaskInstance);

            System.out.println(historicTaskInstance.getName()+"===>"+historicTaskInstance.getAssignee()+"===>"+historicTaskInstance.getStartTime()+"===>"+historicTaskInstance.getEndTime());

        }

    }


猜你喜欢

转载自blog.csdn.net/qq_19734597/article/details/84234443