Activiti7 入门(一)

4,623 阅读15分钟

一、工作流是什么

1.1 工作流:工作的一个流程,事物发展的一个业务过程

 流程:
 请假流程:员工申请----部门经理-----总经理-----人事存档
 传统方式下? 请假条的传递来实现
 无纸化办公? 线上申请----线上审批----一条请假记录

在计算机的帮助下,能够实现流程的自动化控制,就称为工作流.

1.2 工作流引擎

为了实现自动化控制,Activiti引擎就产生了。

作用:实现流程自动化控制

1.3 工作流系统:具有工作流的系统。

如果一个系统具备流程的自动化管理功能,这个系统就可以称为工作流系统

       工作流系统,有哪些手段可以实现?
       工作流系统,如何来实现流程的自动化管理?
       流程自动化管理:程序员编码来实现
       请假:员工申请----部门经理-----总经理-----人事存档

       数据库表: 工号,部门号,姓名,日期,天数,原因,状态

       员工:0未提交1提交
       部门经理:部门号=部门经理的部门编号相同,状态=1
             2同意  3不同意   
       
       总经理    状态=2
             4同意  5不同意

       人事存档  状态=4
             6同意   7不同意  

       问题:业务流程变更后,程序不能使用
             以不变应万变

1.4 如何解决,以不变应万变?

-----Activiti就可以实现业务流程变化后,程序代码不需要改动。

Activiti的原理分析图

二、Acitviti是什么

2.1 Activiti介绍

Activiti是一个项目的名称,Alfresco软件在2010年5月17日宣布Activiti业务流程管理(BPM)开源项目的正式启动,其首席架构师由业务流程管理BPM的专家 Tom Baeyens担任。

Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准,包括支持对象管理组(OMG),面对新技术的机遇,诸如互操作性和云架构,提供技术实现。

2.1.1 BPM

BPM(Business Process Management),即业务流程管理,是一种以规范化的构造端到端的卓越业务流程为中心,以持续的提高组织业务绩效为目的系统化方法,常见商业管理教育如 EMBA、MBA 等均将BPM 包含在内。 企业流程管理主要是对企业内部改革,改变企业职能管理机构重叠、中间层次多、流程不闭环 等,做到机构不重叠、业务不重复,达到缩短流程周期、节约运作资本、提高企业效益的作用。 比较下边的两个人事加薪流程哪个效率更高?

流程一:

流程二:

上边两个流程的区别在于第二个流程在执行时,如果本次加薪金额在一万元以内不再由总经理审批 将比第一个流程缩短流程周期,从而提交效率。 再比较下边的例子,哪个效率更高?

流程一:

流程二:

上边两个流程的区别在于第二个流程将交费和取药放在一起进行,这样导致的结果是此窗口的工作人员必须具备财务、药学专业知识,岗位强度加大,人员培训难度加大从而导致人员不易扩展,工作效率低下。

2.1.2 BPM软件

BPM 软件就是根据企业中业务环境的变化,推进人与人之间、人与系统之间以及系统与系统之间的整合及调整的经营方法与解决方案的 IT 工具。 通常以Internet 方式实现信息传递、数据同步、业务监控和企业业务流程的持续升级优化,从而实现跨应用、跨部门、跨合作伙伴与客户的企业运 作。通过 BPM 软件对企业内部及外部的业务流程的整个生命周期进行建模、自动化、管理监控和优化,使企业成本降低,利润得以大幅提升。

BPM 软件在企业中应用领域广泛,凡是有业务流程的地方都可以 BPM 软件进行管理,比如企业人事办公管理、采购流程管理、公文审批流程管理、财务管理等。

2.1.3 BPMN

BPMN(Business Process Model And Notation)- 业务流程模型和符号 是由 BPMI(Business Process Management Initiative)开发的一套标准的业务流程建模符号,使用BPMN 提供的符号可以创建业务流程。 2004 年 5 月发布了 BPMN1.0 规范.BPMI 于 2005 年 9 月并入 OMG(The Object Management Group 对象管理组织)组织。OMG 于 2011 年 1 月发布BPMN2.0 的最终版本。

三、开发环境准备

1.java环境 --- Jdk1.8
2.数据库 ---  Mysql 5以上版本  此处使用8.0版本
3.web容器 --- tomcat 8以上
4.开发工具 --- IDEA 2019
5.Activiti -Activiti7

3.1 IDEA插件安装

File-Setting-Plugins-搜索 actiBPM 即可,如果IDEA版本较新,商店可能找不到 浏览器打开网址 plugins.jetbrains.com/ 输入actiBPM

按回车键进入,然后点击Version
选择3.E-8 后面的Download进行下载
在IDEA中点击改选项找到刚刚下载的jar包,然后重启

3.2 activiti 建库建表

现在数据库中建立数据库

create database activiti;

使用java代码来创建数据库表 创建Maven工程---导入pom文件依赖

 <properties>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-model</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-converter</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-layout</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>

        <dependency>
            <groupId>org.activiti.cloud</groupId>
            <artifactId>activiti-cloud-services-api</artifactId>
            <version>7.0.0.Beta1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <!-- log start -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- log end -->

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>

        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>

在respurces目录下建立一个log4j.perproties的文件,添加如下内容

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

再建立一个activiti.cfg.xml 里面放入如下内容

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/contex http://www.springframework.org/schema/context/spring-context.xsd
						http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!--    数据源配置-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/activiti?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC&amp;rewriteBatchedStatements=true&amp;allowPublicKeyRetrieval=true" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="maxActive" value="3" />
        <property name="maxIdle" value="1" />
    </bean>
<!--activiti单独运行的ProcessEngine配置,使用单独启动方式-->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!--    配置数据源    -->
        <property name="dataSource" ref="dataSource"></property>
        <!--    是否生成数据库表    -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>

在测试包下创建一个测试类 添加如下代码,执行test方法后,会将数据库表格创建

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;

public class Test {
    @org.junit.Test
    public void testGenTable() {
        //1.创建ProcessEngineConfiguration对象
        ProcessEngineConfiguration configuration =
                ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        //2.创建ProcessEngine对象
        ProcessEngine processEngine = configuration.buildProcessEngine();
        //3.输出ProcessEngine对象
        System.out.println(processEngine);
    }
}

生成后的数据库表格

3.3 Avtiviti数据库表命名规则

Activiti的表都以act_开头,第二部分是表的用途的两个字符的表示。用途和服务的API对应。

  • act_re_* 中 "re" 表示repository。这个前缀的表包含了流程定义和流程的静态资源(图片,规则等)
  • act_ru_* 中 "ru" 表示runtime。这些运行时的二标,包含流程实例,任务,变量,异步任务等运行中的数据。Activiti旨在流程实例中执行过程中保存这些数据,在流程结束时就会删除这些记录。这样运行时表可以一直很小,速度会很快
  • act_hi_* 中 "hi"表示history。这些表包含历史数据,比如历史流程实例,变量,任务等等。
  • act_ge_* 中 "ge"表示general。通用数据,用于不同场景下。

四、Activiti服务架构图

在新版本中,IdentityService FormService这两个service都已经删除了。

4.1 acvitity.cfg.xml

其实该文件就是spring的配置文件,之前的配置里只配置了ProcessEngineConfiguration和数据源。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/contex http://www.springframework.org/schema/context/spring-context.xsd
						http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<!--    数据源配置-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/activiti?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC&amp;rewriteBatchedStatements=true&amp;allowPublicKeyRetrieval=true" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="maxActive" value="3" />
        <property name="maxIdle" value="1" />
    </bean>
<!--activiti单独运行的ProcessEngine配置,使用单独启动方式-->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!--    配置数据源    -->
        <property name="dataSource" ref="dataSource"></property>
        <!--    是否生成数据库表    -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>

4.2 ProcessEngineConfiguration

流程引擎的配置类,通过ProcessEngineConfiguration可以创建工作流引擎 ProcessEngine,一般有两种方式:

一种就4.1中的单独运行的模式。

另一种是通过org.activiti.springProcessEngineConfiguration 与spring整合。

4.3 ProcessEngine

工作流引擎,相当于一个门面接口,通过ProcessEngineConfiguration创建ProcessEngine创建各个service接口。

除了3.2中的创建方式,另一种更加简便的创建方式

        //条件:1.activiti配置文件的默认名称:activiti.cfg.xml  2.bean的id="processEngineConfiguration"
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println(processEngine);

4.4 service

4.4.1 service的创建方式

    DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();
    HistoryService historyService = processEngine.getHistoryService();
    ManagementService managementService = processEngine.getManagementService();

4.4.2 常用的service

RepositoryService avtiviti的资源管理类
RuntimeService avtiviti的流程运行管理类
TaskService avtiviti的任务管理类
HistoryService avtiviti的历史管理类
ManagerService avtiviti的引擎管理类

上面4个是常用的service类

4.4.3 RepositoryService

是 activiti的资源管理类,提供了管理和控制流程发布包和流程定义的操作。使用工作流建模工 具设计的业务流程图需要使用此 service 将流程定义文件的内容部署到计算机。 除了部署流程定义以外还可以: 查询引擎中的发布包和流程定义。 暂停或激活发布包,对应全部和特定流程定义。 暂停意味着它们不能再执行任何操作了,激活 是对应的反向操作。 获得多种资源,像是包含在发布包里的文件, 或引擎自动生成的流程图。 获得流程定义的 pojo 版本, 可以用来通过 java 解析流程,而不必通过 xml。

4.4.4 RuntimeService

它是 activiti的流程运行管理类。可以从这个服务类中获取很多关于流程执行相关的信息

4.4.5 TaskService

是 activiti的任务管理类。可以从这个类中获取任务的信息。

4.4.6 HistoryService

是 activiti 的历史管理类,可以查询历史信息,执行流程时,引擎会保存很多数据(根据配置),比 如流程实例启动时间,任务的参与者, 完成任务的时间,每个流程实例的执行路径,等等。 这个 服务主要通过查询功能来获得这些数据。

4.4.7 ManagementService

是 activiti的引擎管理类,提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动 的应用程序中使用,主要用于 Activiti 系统的日常维护

五、Activiti 入门体验

5.1 流程定义---制作bpmn文件和png文件

之前我们已经安装的Activiti-Designer的插件, 我们在resources目录下建立一个diagram文件夹。 右键创立一个新的BPMN文件命名为holiday。

可以画出一张这样的流程图
将该文件复制一份,后缀改为xml,选中该文件右键,Show BPMN 2.O Designer

进入该页面,点击红框处导出流程图

5.2 流程部署---将定义好的内容注册到数据库表中

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;

public class ActivitiDeployment {
    //流程定义部署
    public static void main(String[] args) {
        //1.创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.进行部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday.bpmn")
                .addClasspathResource("diagram/holiday.png")
                .name("请假申请的流程")
                .key("宝塔镇河妖")
                .deploy();
        //4.输出一些部署的信息
        System.out.println("部署对象的id:"+deploy.getId());
        System.out.println("部署对象的key:"+deploy.getKey());
        System.out.println("部署对象的name:"+deploy.getName());
    }
}

我们查看数据库表 发现有3张表中新增了内容

act_re_deployment --- 部署信息

act_re_procdef --- 流程定义的一些信息

act_ge_bytearray--- 流程定义的bpmn文件以及png文件

5.3 流程实例---流程定义的一个实例

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;

/*
流程启动实例
 */
public class ActivitiStartInstance {
    public static void main(String[] args) {
        //1.得到ProcessEngine对象
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.得到RunService对象
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
        //3.创建流程实例
        ProcessInstance holiday = runtimeService.startProcessInstanceByKey("holiday");
        //4.输出流程实例的相关信息
        System.out.println("部署ID:"+holiday.getDeploymentId());
        System.out.println("名称:"+holiday.getName());
        System.out.println("ID:"+holiday.getId());
        System.out.println("商业KEY:"+holiday.getBusinessKey());
        System.out.println("实例ID:"+holiday.getActivityId());
    }
}

运行完成以后 我们会发现背后影响的表有:

act_hi_actinst---已完成活动信息

act_hi_identitylink---参与者信息

act_hi_procinst---流程实例

act_hi_taskinst---任务实例

act_ru_execution---执行表

act_ru_idemtitylink---参与者信息

act_ru_task---执行中任务

5.4 任务查询

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;

import java.util.List;

public class ActivitiTaskQuery {
    public static void main(String[] args) {
        //1.湖片区ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取taskServic
        TaskService taskService = processEngine.getTaskService();
        //3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("holiday")
                .taskAssignee("zhangsan").list();
        //4.任务列表的展示
        for (Task task : list) {
            System.out.println("流程实例id:"+task.getProcessInstanceId());
            System.out.println("任务id:"+task.getId());
            System.out.println("任务负责人:"+task.getAssignee());
            System.out.println("任务名称:"+task.getName());
        }
    }
}

5.5 任务执行

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.TaskService;

public class ActivitiCompleteTask {
    public static void main(String[] args) {
        //1.获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取taskService
        TaskService taskService = processEngine.getTaskService();
        //3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
        taskService.complete("2505");
    }
}

处理当前用户任务背后操作的表:

act_hi_actinst---已完成活动信息

act_hi_identitylink---参与者信息

act_hi_taskinst---任务实例

act_ru_execution---执行表

act_ru_identitylink---参与者信息

act_ru_task---执行中任务

可以试着把请假任务一步步查询(执行人可以去数据库中查询)并且执行完,,然后看看以上几张表中会发生什么变化。

六、流程定义

6.1 流程定义的查询

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;

import java.util.List;

public class QueryProcessDefinition {
    public static void main(String[] args) {
        //1.获取ProcessEngine引擎对象
        ProcessEngine processEngine =
                ProcessEngines.getDefaultProcessEngine();
        //2.创建RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.获取ProcessDefinitionQuery对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        //4.设置条件,并且查询出当前的所有流程的定义,查询条件:流程定义的key=holiday 设置排序方式

        List<ProcessDefinition> holiday =
                processDefinitionQuery.processDefinitionKey("holiday").
                orderByProcessDefinitionVersion().
                desc().list();
        //5.输出流程定义的信息
        for (ProcessDefinition processDefinition : holiday) {
            System.out.println("流程定义的ID"+processDefinition.getId());
            System.out.println("流程定义的名称"+processDefinition.getName());
            System.out.println("流程定义的key"+processDefinition.getKey());
            System.out.println("流程定义的版本"+processDefinition.getVersion());
        }
    }

使用上述可以查询到已经部署的流程定义信息

6.2 删除流程定义信息

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;

public class DeleteProcessDefinition {
    public static void main(String[] args) {
        //1.获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.创建repositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.执行删除流程
        repositoryService.deleteDeployment("1");
    }
}

我们查看数据库表

发现部署时的三张表里面的信息被删除

act_re_deployment --- 部署信息

act_re_procdef --- 流程定义的一些信息

act_ge_bytearray--- 流程定义的bpmn文件以及png文件

注意:

  • 如果当前要删除的流程定义信息有任务没有执行完成,删除会失败
  • 若果要强制删除,可以repositoryService.deleteDeployment("1",true),会将正在运行的任务也删除。

6.3 流程定义文件获取

先引入IO工具包

<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.7</version>
        </dependency>
/*
需求:
1.从Activiti的act_ge_bytearray表中读取两个资源文件
2.将资源文件保存到本地路径中
技术方案:
        1.使用activiti的api来实现
        2.用JDBC对blob clob类型数据的读取
        3.IO流的转换 commons-io.jar
 */

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.io.IOUtils;


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;


public class QueryBpmnFile {
    public static void main(String[] args) throws IOException {
        //1.获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.创建repositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.获取ProcessDefinitionQuery对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        //4.设置条件,并且查询出当前的所有流程的定义,查询条件:流程定义的key=holiday 设置排序方式
        ProcessDefinition holiday =
                processDefinitionQuery.processDefinitionKey("holiday").singleResult();
        //5.查询流程定义信息,得到部署ID
        String deploymentId = holiday.getDeploymentId();
        //6.通过repositoryService的方法,实现读取文件信息以及BPMN文件信息(输入流)
        //第一个参数时部署ID,第二个名字叫资源名称
        InputStream pngIS = repositoryService.getResourceAsStream(deploymentId, holiday.getDiagramResourceName());//png文件
        InputStream bpmnIS = repositoryService.getResourceAsStream(deploymentId, holiday.getResourceName());//BPMN文件
        //7.构建输出流
        System.out.println(holiday.getDiagramResourceName());
        FileOutputStream pngOS = new FileOutputStream("D:\\gitSource\\Activiti\\src\\main\\resources\\"+holiday.getDiagramResourceName().split("/")[1]);
        FileOutputStream bpmnOS = new FileOutputStream("D:\\gitSource\\Activiti\\src\\main\\resources\\"+holiday.getResourceName().split("/")[1]);
        //8.输入流输出流的转换
        IOUtils.copy(pngIS,pngOS);
        IOUtils.copy(bpmnIS,bpmnOS);
        //9.流的关闭
        pngOS.close();
        pngIS.close();
        bpmnOS.close();
        bpmnIS.close();
    }
}

6.4 历史流程定义查询

package com.bin.activiti.dingyi;

import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.history.HistoricDetailQuery;

import java.util.List;

public class HistoryQuery {
    public static void main(String[] args) {
        //1.获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取HistoryService对象
        HistoryService historyService = processEngine.getHistoryService();
        //3.获取查询historicActivityInstanceQuery对象
        HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
        historicActivityInstanceQuery.processInstanceId("2501").orderByHistoricActivityInstanceStartTime().asc();//设置流程实例的id
        //4.执行查询
        List<HistoricActivityInstance> list = historicActivityInstanceQuery.list();

        //5.输出查询结果
        for (HistoricActivityInstance historicActivityInstance : list) {
            System.out.println(historicActivityInstance.getActivityId());
            System.out.println(historicActivityInstance.getId());
            System.out.println(historicActivityInstance.getProcessInstanceId());
            System.out.println(historicActivityInstance.getActivityName());
            System.out.println(historicActivityInstance.getProcessDefinitionId());
            System.out.println("-----------------------------");
        }

    }
}