在工作流中,我们一切工作流的基本就是工作引擎(ProcessEngine),继承于EngineService接口,包括流程部署,数据库连接都是靠着ProcessEngine来实现的。而ProcessEngineConfiguration:流程引擎配置,可以设置数据库等,默认的数据库是h2,持久化实现使用的Mybatis,这里我们用的是mysql。

       那么既然无论是jbpm或者是activiti都需要ProcessEngine来驱动,那么我们就说一下工作流引擎的使用吧。

       流程部署

       当我们将我们的业务画成图的时候,然后利用工作流引擎部署,也就是将我们的流程图信息放到数据库,图和代码如下:

        

[java] view plain copy

  1. /**部署流程定义*/  

  2.     @Test  

  3.     public void deploymentProcessDefinition(){  

  4.         Deployment deployment = processEngine.getRepositoryService()  //用于流程定义和部署相关对象的Service  

  5.                         .createDeployment()   //创建一个部署对象  

  6.                         .name("leaveBill部门程序")  

  7.                         .addClasspathResource("diagrams/LeaveBill.bpmn"//从ClassPath资源中加载,一次只能加载一个文件  

  8.                         .addClasspathResource("diagrams/LeaveBill.png")  //从ClassPath资源中加载,一次只能加载一个文件  

  9.                         .deploy();  

  10.           

  11.         System.out.println("deployment" + deployment.getId());   //1  

  12.         System.out.println("deployment" + deployment.getName());//部门程序  

  13.       

  14.     }  

      打印结果如下:

      deployment1
      deploymenthellworld部门程序

      数据库(部署相关表)解析

      我们看一下数据库的表会发现,每次部署都是涉及的那三张表,act_re_deployment(流程部署表)

      该表包含了流程部署的名称,ID,和部署时间

         act_re_procdef(流程定义表)

      该表有流程定义的主键key,版本(version)源文件名和图示,还有流程定义ID(key + 版本号+随机生成的数字)

     act_ge_bytearray(资源文件表)    

       保存了资源的位置和存储方式和部署ID,版本号ID等信息

      act_ge_property:主键生成策略表

         定义了主键生成的策略信息

        执行流程

        顾名思义,就是当我们有一个人开始申请请假的时候我们就要执行该请假的流程实例了

[java] view plain copy

  1. /** 

  2.  * 执行流程实例 

  3.  */  

  4. @Test  

  5. public void startProcessInstance(){  

  6.     String processInstanceKey = "LeaveBill";  

  7.     ProcessInstance pi = processEngine.getRuntimeService()  

  8.                         .startProcessInstanceByKey(processInstanceKey);  

  9.     System.out.println("流程实例id:" + pi.getId());  //流程实例id  101  

  10.     System.out.println("流程定义id:" + pi.getProcessDefinitionId());   //流程定义ID helloworld:1:4  

  11. }  

        这样我们的流程实例就启动起来了,那么接下来我们看一下在启动流程实例的时候我们涉及到的表信息

      数据库分析(实例表)分析

       act_ru_execution: 正在执行的执行对象表,侧重流程实例,对象,任务

       包含了实例ID,流程定义ID,要执行的任务名称(usertask1)等信息

       act_ru_task:正在执行的任务表,对具体的任务而言,任务执行到哪里了

      

     act_ru_identitylink流程信息变量act_hi_taskinst:已经执行完的历史任务信息

act_hi_taskinst:已经执行完的历史任务信息
act_hi_procinst:流程实例的历史表,存放执行完毕的流程实例信息

act_hi_actinst:存放历史所有完成的活动

           现在我们对表有一个大致的了解,那么接下来我们就按照我们既定的流程去执行我们的请假,例如第一个项目经理叫张三,那么这个流程实例已启动,首先需要张三去执行操作,那么我们我们看一下张三的执行任务的详情,代码如下:

[java] view plain copy

  1. /** 

  2.      * 查找个人当前的要执行的任务 

  3.      */  

  4.     @Test  

  5.     public void findMyTaskInfo(){  

  6.         String assignee = "张三";  

  7.         List<Task> listTask = processEngine.getTaskService()  

  8.             .createTaskQuery()  

  9.             .taskAssignee(assignee)  

  10.             .list();  

  11.           

  12.         if (listTask!= null && listTask.size() >0) {  

  13.             for (Task task : listTask) {  

  14.                 System.out.println("任务ID:" + task.getId());  

  15.                 System.out.println("任务名称:" + task.getName());  

  16.                 System.out.println("任务时间:" + task.getCreateTime());  

  17.                 System.out.println("任务的班里人:" + task.getAssignee());  

  18.                 System.out.println("任务的实例ID:" + task.getProcessDefinitionId());  

  19.                 System.out.println("执行对象的ID:" + task.getExecutionId());  

  20.                 System.out.println("任务的班里人:" + task.getAssignee());  

  21.                 System.out.println("流程定义ID:" + task.getProcessInstanceId());  

  22.             }  

  23.         }  

  24.               

  25.           

  26.     }  

       打印信息如下:任务ID:304,任务名称:【项目经理】审批,任务时间:Sat Jan 23 14:54:35 CST 2016,任务的班里人:张三 任务的实例ID:LeaveBill:2:204     执行对象的ID:301   任务的班里人:张三  流程定义ID:301

       任务完成

        那么接下来我就把任务ID为304的一个流程结束,也就是项目经理同意请假,代码如下:

[java] view plain copy

  1. /**完成任务*/  

  2. @Test  

  3. public void completeMyPersoinTask() {  

  4.     String taskId = "304";  

  5.     processEngine.getTaskService()  

  6.     .complete(taskId);  

  7.       

  8.     System.out.println("完成任务,任务ID:" + taskId);  

  9. }  

        然后我继续执行查询个人任务的时候,我们只能查到主任的任务了,因为项目经理已经执行完毕,所以当前执行的任务是看不到的,但是在历史信息中是存在的。

       如果我们启动了实例的话,查询当前信息的话,实在act_ru_*的表中查询,根据任务有关的服务,都是taskService,当然Activiti还有很多的服务,例如RepositoryService,RuntimeService, HistoryService等服务。

      大致总结一下,就是先部署,再启动,个人登陆系统后,根据个人姓名,查到任务ID,完成个人任务,直到全部完成