纵有疾风起
人生不言弃

Activiti5工作流笔记一


介绍工作流

  网上工作流的定义一大堆,这里就不去复制了,通俗的理解,工作流就是类似OA系统中请假审批、报销审批等一系列流程,下级提交的申请只有直系领导才能审批,其他人是没有权限的,而只有直系领导审批通过后,直系领导的直系领导才可以看到申请,并进行审批,以此类推。。。

  而Activiti工作流就可以实现类似的功能,本笔记将以最简单的方式让你明白怎么使用Activiti工作流,直接上代码

准备环境

1) JDK1.6或者更高版本

2) 支持的数据库有:h2, mysql, oracle, postgres, mssql, db2等。

3) 支持activiti5运行的jar包

4) 开发环境为Eclipse3.7或者以上版本,myeclipse为8.6版本

安装流程设计器(eclipse插件)

方案一:

有网络的情况下,安装流程设计器步骤如下:

1) 打开 Help -> Install New Software. 在如下面板中:

Activiti5工作流笔记一插图

2) 在如下Install界面板中,点击Add按钮:

 Activiti5工作流笔记一插图(1)

3) 然后填入下列字段

Name: Activiti BPMN 2.0 designer

Location: http://activiti.org/designer/update/

4) 回到Install界面,在面板正中列表中把所有展示出来的项目都勾上:

Activiti5工作流笔记一插图(2)

5) 点击复选框

Detail部分记得选中 “Contact all updates sites..” , 因为它会检查所有当前安装所需要的插件并可以被Eclipse下载.

6) 安装完以后,点击新建工程new->Other…打开面板,如果看到下图内容:

说明安装成功了。

 Activiti5工作流笔记一插图(3)

方案二

没有网络的情况下,安装流程设计器步骤如下:

首先下载离线插件包:

 https://files.cnblogs.com/files/lm970585581/activiti.zip

将压缩包解压后

Activiti5工作流笔记一插图(4)

这两个文件夹复制到Eclipse根目录下 ,重启即可

注意:

打开菜单Windows->Preferences->Activiti->Save下流程流程图片的生成方式:

Activiti5工作流笔记一插图(5)

虽然流程引擎在单独部署bpmn文件时会自动生成图片,但在实际开发过程中,自动生成的图片会导致和BPMN中的坐标有出入,在实际项目中展示流程当前位置图会有问题。

所在完成以上配置后,会由我们自己来管理流程图片。在发布流程时把流程规则文件和流程图片一起上传就行了。

准备Activiti5开发环境

 

activiti-5.13->wars目录下是一些示例项目,解压activiti-rest项目,导入activiti-rest目录中WEB-INF\lib下所有包。添加到classpath中。

另外需要根据我们正在使用的数据库添加相应的数据库jar包

 

初始化数据库

可以在activiti-rest\WEB-INF\classes下找到配置文件:如下

 

<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"    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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">        <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>        <property name="jdbcUrl" value="jdbc:mysql://192.168.220.130:3306/activiti?useUnicode=true&amp;characterEncoding=utf8"></property>        <property name="jdbcUsername" value="root"></property>        <property name="jdbcPassword" value="root"></property>        <!--             创建表的策略         -->        <property name="databaseSchemaUpdate" value="true"></property>    </bean></beans>

 

调用以下java代码,即可把需要的表创建出来

import org.activiti.engine.ProcessEngine;import org.activiti.engine.ProcessEngineConfiguration;import org.junit.Test;public class CreateTable {    @Test    public void testCreateTable(){        ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")            .buildProcessEngine();    }}

HelloWorld程序

 

 先画请假流程图

Activiti5工作流笔记一插图(6)

注意:

properties=>General中的ID和NAME可以设置每个步骤的名称:

Activiti5工作流笔记一插图(7)

 

每个审批过程的properties=>Main config=>Assignee:设置能够审批的对象,这里部门经理审批设置为:张三,总经理审批设置为:李四

Activiti5工作流笔记一插图(8)

 

保存后,在根目录下生成:Activiti5工作流笔记一插图(9)

JAVA程序如下:

import java.util.List;import org.activiti.engine.ProcessEngine;import org.activiti.engine.ProcessEngineConfiguration;import org.activiti.engine.ProcessEngines;import org.activiti.engine.task.Task;import org.junit.Test;/** * 1、部署流程图 * 2、启动流程实例 * 3、发起申请 * 4、审批 * @author zd * */public class HelloWorld {    /**     * 部署流程图     */    @Test    public void testDeploy(){        //产生流程引擎        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        //获取仓库流程的实例        processEngine.getRepositoryService()        .createDeployment()        .addClasspathResource("qingjia.bpmn")        .addClasspathResource("qingjia.png")        .deploy();        /**         * 这里使用RepositoryService部署流程定义           addClasspathResource表示从类路径下加载资源文件,一次只能加载一个文件         */    }        /**     * 启动流程实例  pi=process instance     */    @Test    public void testStartPI(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        processEngine.getRuntimeService()        .startProcessInstanceById("qingjia:1:4");//ID在act_re_procdef这个表中可以看到        //这里使用RuntimeService启动流程实例    }        /**     * 完成任务     */    @Test    public void testFinishTask(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        processEngine.getTaskService()        .complete("104");//act_ru_task表中获取    }        /**     * 根据张三查询任务     */    @Test    public void testQueryTask(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        //查询任务列表        List<Task> tasks = processEngine.getTaskService()        .createTaskQuery()        .taskAssignee("张三")        .list();        for (Task task : tasks) {            System.out.println(task.getName());        }    }}

流程定义

import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.util.List;import java.util.zip.ZipInputStream;import org.activiti.engine.ProcessEngine;import org.activiti.engine.ProcessEngines;import org.activiti.engine.repository.Deployment;import org.activiti.engine.repository.ProcessDefinition;import org.junit.Test;import org.springframework.transaction.annotation.Transactional;/** * pd=process definition * @author zd *   1、把流程图部署到activiti的引擎中   重点 *       classpath *       inputstream *       zipinputstream *   2、对流程图进行删除   重点 *   3、获取到流程图和bpmn文件  重点 *   4、查询  了解 *      查询部署 *      查询流程定义 */public class PDTest {    /**     * 涉及到的表     *     act_ge_bytearray     *         1、说明     *             该表存储了bpmn文件和png图片     *             从字段可以看出,根据deploymentID可以查询bpmn文件和png图片     *         2、字段     *             name_:存储该文件的路径名称     *             deploymentid_id_:部署表的ID     *             byte_:存放值(bpmn和png)     *     act_re_deployment     *         1、说明     *             该表存储了部署的动作     *         2、字段     *            ID_:部署ID 主键     *     act_re_procdef     *         1、说明     *             流程定义表     *         2、字段     *                id: 是由${name}:${version}:随机数   确定唯一的流程     *             name_: 流程定义名称     *             key_:  流程定义名称     *             version_:  某一个流程定义的版本     *             deployment_id_:部署表的ID     *                  *  说明:     *      1、根据deploymentID-->查询图片和bpmn文件     *      2、根据deploymentID-->查询流程定义     *      3、只要流程名称不变,部署一次,版本号加1,id就发生变化,生成了一个新的deploymentID     *      4、所以deploymentID和pdid是一一对应的关系     */    @Test    public void testDeployFromClasspath(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        processEngine.getRepositoryService()        .createDeployment()        .addClasspathResource("qingjia.bpmn")        .addClasspathResource("qingjia.png")        .deploy();    }        /**     * 通过inputStream的方式部署     */    @Test    public void testDeployFromInputStream(){        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("qingjia.bpmn");        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        processEngine.getRepositoryService()        .createDeployment()        .addInputStream("qingjia.bpmn", inputStream)        .deploy();    }        /**     * 通过zip的方式部署     */    @Test    public void testDeployFromZip(){        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("qingjia.zip");        ZipInputStream zipInputStream = new ZipInputStream(inputStream);        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        processEngine.getRepositoryService()        .createDeployment()        .addZipInputStream(zipInputStream)        .deploy();    }        /**     * 把查询出来的图片放到E盘的根目录下     */    @Test    public void testShowImage() throws Exception{        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        InputStream inputStream = processEngine.getRepositoryService()        /**         * 参数为pdid         */        .getProcessDiagram("qingjia:1:4");        /**         * 得到一个图片         */        //    OutputStream outputStream = new FileOutputStream("e:/processimg.png");        //    for(int b=-1;(b=inputStream.read())!=-1;){        //        outputStream.write(b);        //    }        //    inputStream.close();        //    outputStream.close();        /***************************************************************************************/        /**         *   第一个参数为deploymentId         *   第二个参数为resourceName         */        /********************************************************************************/        /**         * 得到的是一个图片         */            //        InputStream inputStream2 = processEngine.getRepositoryService()            //        .getResourceAsStream("101", "qingjia.png");            //                    //        OutputStream outputStream2 = new FileOutputStream("e:/processimg2.png");            //        for(int b=-1;(b=inputStream2.read())!=-1;){            //            outputStream2.write(b);            //        }            //        inputStream2.close();            //        outputStream2.close();            /**********************************************************************************/        /**         * 得到的是bpmn文件          */        InputStream inputStream3 = processEngine.getRepositoryService()        .getProcessModel("qingjia:1:4");        OutputStream outputStream3 = new FileOutputStream("e:/processimg3.bpmn");        for(int b=-1;(b=inputStream3.read())!=-1;){            outputStream3.write(b);        }        inputStream3.close();        outputStream3.close();        /*************************************************************************************/    }        /**     * 查询流程部署     */    @Test    public void testQueryDeploy(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<Deployment> deployments = processEngine.getRepositoryService()        .createDeploymentQuery()        .list();        for (Deployment deployment : deployments) {            System.out.println(deployment.getId());        }    }        /**     * 根据部署ID查询部署  一个结果     */    @Test    public void testQueryDeployById(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        Deployment deployment = processEngine.getRepositoryService()        .createDeploymentQuery()        .deploymentId("1")        .singleResult();                    System.out.println(deployment.getId());            }        /**     * 查询所有的流程定义     */    @Test    public void testQueryPD(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<ProcessDefinition> processDefinitions = processEngine.getRepositoryService()        .createProcessDefinitionQuery()        .list();        for (ProcessDefinition processDefinition : processDefinitions) {            System.out.println(processDefinition.getKey());            System.out.println(processDefinition.getId());            System.out.println(processDefinition.getVersion());        }    }        /**     * 按照版本的从高到低进行排序     */    @Test    public void testQueryPDByVersion(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<ProcessDefinition> processDefinitions = processEngine.getRepositoryService()        .createProcessDefinitionQuery()        .orderByProcessDefinitionVersion()        .desc()        .list();        for (ProcessDefinition processDefinition : processDefinitions) {            System.out.println(processDefinition.getKey());            System.out.println(processDefinition.getId());            System.out.println(processDefinition.getVersion());        }    }        /**     * 根据pdid查询流程定义     * 根据 pdkey查询流程定义     */    //略。。        /**     * 删除     */    @Test    public void testDelete(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        processEngine.getRepositoryService()        //.deleteDeployment("");//该方法只能删除流程定义,一般不会使用        .deleteDeployment("1", true);//该方法不仅能够删除流程定义,而且能够删除正在运行的流程实例    }}

流程实例、任务的执行

 

import java.util.List;import org.activiti.engine.ProcessEngine;import org.activiti.engine.ProcessEngines;import org.activiti.engine.history.HistoricActivityInstance;import org.activiti.engine.history.HistoricTaskInstance;import org.activiti.engine.impl.bpmn.parser.handler.ProcessParseHandler;import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;import org.activiti.engine.impl.pvm.process.ActivityImpl;import org.activiti.engine.runtime.ProcessInstance;import org.activiti.engine.task.Task;import org.junit.Test;/** * pi=process instance * @author zd * 1、启动流程实例 * 2、完成任务 * 3、任务的查询 *         1、根据任务的执行人查询任务 *         2、可以根据任务查询任务的执行人 *         3、查看历史任务 * 4、怎么样查看流程实例是否结束 */public class PITest {    /**     * 启动流程实例     *    涉及到的表     *       act_hi_actinst   hi:history   actinst:action instance     *          1、概念     *               所有的正在执行的或者已经完成的节点     *          2、字段     *              act_type_:为节点的类型     *              end_time_: 如果有值,说明该节点已经结束了     *       act_hi_procinst   procinst:process instance     *          1、概念     *               所有的正在执行的或者已经完成的流程实例     *          2、字段     *               end_time_:如果该字段有值,说明这个流程实例已经结束了     *               end_act_id_:说明该流程实例是在哪个节点结束的     *       act_hi_taskinst   taskinst:task instance     *          1、概念     *              所有的正在执行的或者已经完成的任务节点     *          2、字段     *              end_time_:如果该字段有值,说明任务已经完成了     *              delete_reason:如果该值为completed,说明该任务处于完成的状态     *       act_ru_execution  ru:runtime        *          1、概念     *              代表正在执行的流程实例      *          2、字段     *              id_:主键  executionid     *              proc_inst_id_:  process instanceid     *              proc_def_id_:pdid     *              act_id_:当前的流程实例正在执行的节点的ID的值     *       act_ru_task     *          1、概念     *              代表正在执行的任务     *          2、字段     *             id_:主键   任务ID     *             execution_id_:piid,executionid     *             name_:任务名称     *          3、说明     *               该表是一个临时表,该表中的任务完成以后,这一行会被删除掉        *                   */    @Test    public void testStartPI(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        ProcessInstance pi = processEngine.getRuntimeService()        .startProcessInstanceById("qingjia:1:304");        System.out.println(pi.getId());    }        /**     * 查询所有的正在执行的流程实例     */    @Test    public void testQueryPI(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<ProcessInstance> processInstances = processEngine.getRuntimeService()        .createProcessInstanceQuery()        .list();        for (ProcessInstance processInstance : processInstances) {            System.out.println(processInstance.getActivityId());            System.out.println(processInstance.getId());        }    }        /**     * 查询当前正在执行的节点     */    @Test    public void testQueryActivity(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<String> strings = processEngine.getRuntimeService()        .getActiveActivityIds("401");        for (String string : strings) {            System.out.println(string);        }    }        /**     *获取当前的流程实例正在运行的节点的坐标     */    @Test    public void getPix(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        /**         * processDefinitionEntity代表流程图对象的实体         *          * 根据pdid获取到流程定义实体         */        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)processEngine.getRepositoryService()                .getProcessDefinition("qingjia:1:304");        List<String> strings = processEngine.getRuntimeService()                .getActiveActivityIds("401");  //piid        for (String string : strings) {            /**             * ActivityImpl代表流程图上的每一个节点             */            ActivityImpl activityImpl = processDefinitionEntity.findActivity(string);            /**             * 获取到正在执行的流程节点的坐标             */            System.out.println(activityImpl.getHeight());            System.out.println(activityImpl.getWidth());            System.out.println(activityImpl.getX());            System.out.println(activityImpl.getY());        }    }        /**     * 查询所有的任务     */    @Test    public void testQueryAllTask(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<Task> tasks = processEngine.getTaskService()        .createTaskQuery()        .list();        for (Task task : tasks) {            System.out.println(task.getId());            System.out.println(task.getName());        }    }        /**     * 完成任务     *    需要一个参数:taskId     */    @Test    public void testFinishTask(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        processEngine.getTaskService()        .complete("602");    }        /**     * 根据任务的执行人查看任务     */    @Test    public void testQueryTaskByAssignee(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<Task> tasks = processEngine.getTaskService()        .createTaskQuery()        .taskAssignee("张三")        .list();        for (Task task : tasks) {            System.out.println(task.getId());            System.out.println(task.getName());        }    }        /**     * 根据任务的执行人查看任务,并且按照时间的倒叙排序     */    @Test    public void testQueryTaskByAssigneeByTime_DESC(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<Task> tasks = processEngine.getTaskService()        .createTaskQuery()        .taskAssignee("张三")        .orderByTaskCreateTime()        .desc()        .list();        for (Task task : tasks) {            System.out.println(task.getId());            System.out.println(task.getName());        }    }        /**     * 根据piid判断流程实例是否结束     */    @Test    public void testQueryPIByPIID(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        ProcessInstance pi = processEngine.getRuntimeService()        .createProcessInstanceQuery()        .processInstanceId("401")        .singleResult();        if(pi==null){            System.out.println("该流程实例已经结束了");        }else{            System.out.println("该流程实例正在执行中");        }    }            /**     * 查询已经完成的任务     */    @Test    public void testQueryHistoryTask(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<HistoricTaskInstance> historicTaskInstances = processEngine.getHistoryService()        .createHistoricTaskInstanceQuery()        .finished()        .list();        for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {            System.out.println(historicTaskInstance.getAssignee());            System.out.println(historicTaskInstance.getName());            System.out.println(historicTaskInstance.getId());        }    }        /**     * 查询已经完成的activityimpl     */    @Test    public void testQueryHistoryActivityImpl(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        List<HistoricActivityInstance> historicActivityInstances = processEngine.getHistoryService()        .createHistoricActivityInstanceQuery()        .list();        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {            System.out.println(historicActivityInstance.getActivityName());        }    }}

Activiti5工作流笔记二

文章转载于:https://www.cnblogs.com/lm970585581/p/9308745.html

原著是一个有趣的人,若有侵权,请通知删除

未经允许不得转载:起风网 » Activiti5工作流笔记一

分享到: 生成海报
avatar

评论 抢沙发

评论前必须登录!

立即登录   注册

切换注册

登录

忘记密码 ?

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活