Activiti学习笔记四 流程定义的管理(一)

来源:互联网 发布:佛教网站源码 编辑:程序博客网 时间:2024/04/30 11:45

上一篇模拟了流程执行,这一篇来看下流程定义的管理。

1.设计流程定义文档

  • 流程图

  • BPMN文件

        BPMN 2.0根节点是definitions节点。 这个元素中,可以定义多个流程定义(不过建议每个文件只包含一个流程定义, 这样可以简化开发过程中的维护难度)。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的声明。 targetNamespace可以是任意值,它用来对流程实例进行分类。

 

说明:流程定义文档由两部分组成:

        1)bpmn文件

              流程规则文件。在部署后,每次系统启动时都会被解析,把内容封装成流程定义放入项目缓存中。Activiti框架结合这个xml文件自动管理流程,流程的执行就是按照bpmn文件定义的规则执行的,bpmn文件是给系统执行用的

        2)流程图的png图片

              在系统里需要展示流程的进展状况,图片是给用户看的

2.部署流程定义(classpath路径加载)

    private final ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();    /**     * 功能: 部署流程定义classpath.<br/>     * date: 2014年12月16日 下午1:02:11 <br/>     *      * @author xzzhao@wisdombud.com     */    @Test    public void deploymentProcessDefinitionByClassPath() {        Deployment deployment = processEngine.getRepositoryService()                // 与流程定义和部署相关的Service                .createDeployment()                // 创建部署对象                .name("流程定义")                // 部署名称                .addClasspathResource("diagrams/helloworld.bpmn").addClasspathResource("diagrams/helloworld.png")                .deploy(); // 部署        System.out.println("部署ID:" + deployment.getId());        System.out.println("部署名称:" + deployment.getName());    }


   说明:

         1)先获取流程引擎对象:在创建时会自动加载classpath下的activiti.cfg.xml。

         2)通过流程引擎获取了一个RepositoryService对象(仓库服务对象)。

         3)由仓库的服务对象产生一个部署对象配置对象,用来封装部署操作的相关配置。

         4)在部署配置对象中设置显示名,上传流程定义规则文件。

         5) 向数据库表中存放流程定义的规则信息。

  添加操作设计到数据库中的三张表:

         1. act_re_deployment(部署对象表)

            存放流程定义的名称和部署时间,每部署一次增加一条记录。

          

        2.act_re_procdef(流程定义表)

存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。

注意:当流程定义的key相同的情况下,使用的是版本升级。

       3.act_ge_bytearray(资源文件表)

            存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片的(如果部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都是以二进制形式存储在数据库中。

          

         4. act_ge_property (主键生成策略表) (顺带提下)

           这是一张主键生成策略表。

          

2.部署流程定义(zip格式文件)

          首先将两个流程定义文档helloworld.bpmn和helloworld.png打包为zip格式的文件放到resource目录,使用zip的输入流部署流程定义。

         

/**     * 功能: 部署流程定义zip.<br/>     * date: 2014年12月16日 下午2:09:03 <br/>     *      * @author xzzhao@wisdombud.com     */    @Test    public void deploymentProcessDefinitionByZip() {        InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");        ZipInputStream zipInputStream = new ZipInputStream(in);        Deployment deployment = processEngine.getRepositoryService()        // 与流程定义和部署相关的Service                .createDeployment()                // 创建部署对象                .name("流程定义")                // 部署名称                .addZipInputStream(zipInputStream) // 指定zip文件                .deploy(); // 部署        System.out.println("部署ID:" + deployment.getId());        System.out.println("部署名称:" + deployment.getName());    }


3.查看流程定义

/**     * 功能: 流程定义的查询.<br/>     * date: 2014年12月16日 下午2:58:21 <br/>     *      * @author xzzhao@wisdombud.com     */    @Test    public void queryProcessDefinition() {        List<ProcessDefinition> list = processEngine.getRepositoryService()// 与流程定义和部署对象相关Service                .createProcessDefinitionQuery() // 创建流程定义查询                // .deploymentId(deploymentId) 使用部署对象Id查询                // .processDefinitionId(processDefinitionId) 使用流程定义Id查询                // .processDefinitionKey(processDefinitionKey) 使用流程定义key查询                // .processDefinitionNameLike(processDefinitionNameLike)                // 使用流程定义名称模糊查询 ...                /** 排序 */                // .orderByProcessDefinitionVersion().asc() 按照版本的升序排列                // .orderByProcessDefinitionName().desc() 按照流程定义名称降序排列                // .singleResult(); 返回唯一结果集                // .count() 返回记录数                // .listPage(firstResult, maxResults) 分页查询                .list();// 返回集合        if (null != list && list.size() > 0) {            for (ProcessDefinition pd : list) {                System.out.println("流程定义ID:" + pd.getId()); // key + 版本 + 随机数                System.out.println("流程定义的名称:" + pd.getName()); // 对应bpmn文件中Name属性                System.out.println("流程定义的key:" + pd.getKey()); // 对应bpmn文件中ID属性                System.out.println("流程定义的版本:" + pd.getVersion()); // 当流程定义的key值相同下,版本升级,默认是1                System.out.println("部署对象的ID:" + pd.getDeploymentId());                System.out.println("资源文件bpmn名称:" + pd.getResourceName());                System.out.println("资源文件png名称:" + pd.getDiagramResourceName());                System.out.println("############################################");            }        }    }

 

说明:

        1)流程定义和部署对象相关的Service都是RepositoryService。

        2)创建流程定义查询对象,可以在ProcessDefinitionQuery上设置查询的相关参数。

        3)调用ProcessDefinitionQuery对象的list方法,执行查询,获得符合条件的流程定义列表。

        4)由运行结果可以看出Key和Name的值为:bpmn文件process节点的id和name的属性值

      5)key属性被用来区别不同的流程定义。

      6)带有特定key的流程定义第一次部署时,version为1。之后每次部署都会在当前最高版本号上加1。

      7)Id的值的生成规则为:{processDefinitionKey}:{processDefinitionVersion}:{generated-id},这里的generated-id是一个自动生成的唯一的数字。

      8)重新部署一次,deploymentId的值是由规则变化的,具体规则由act_ge_property表生成。

4.删除流程定义

/**     * 功能: 删除流程定义.<br/>     * date: 2014年12月16日 下午3:41:06 <br/>     *      * @author xzzhao@wisdombud.com     */    @Test    public void deleteProcessDefinition() {        // 使用部署Id删除        String deploymentId = "901";        // 不带级联删除,只能删除没有启动的流程,流程启动则抛出异常        // processEngine.getRepositoryService().deleteDeployment(deploymentId);        // 级联删除,会删除该流程所有相关的信息,包括历史信息        processEngine.getRepositoryService().deleteDeployment(deploymentId, true);        System.out.println("删除成功!");    }


说明:

        1)删除流程定义首先获取RepositoryService。

        2)如果该流程定义下没有正在运行的流程,则可以用普通删除。如果是有关联的信息,用级联删除。实际项目开发中使用级联删除的情况比较多,删除操作一般只开放给超级管理员使用。

 

 

 

 

0 0