Activiti7初级体验,了解工作流的实现原理

activiti使用到的类的介绍:

RepositoryService: 操作和管理流程的定义和部署,deployment(部署)是ProcessEngine的基本单元

RuntimeService:每一个流程都可以创建许多的运行实例,RuntimeService启动流程的实例,检索和存储实例的变量信息

IdentityService:管理组和用户的身份认证信息

FormService:可选的服务

HistoryService:检索ProcessEngine的历史数据

ManagementService:检索数据库的元数据和表的信息,在编程的时候一般用不到

DynamicBpmnService:动态的改变流程的定义,并且不需要重新部署,在生产环境很少使用

使用Java代码生成表

将bomn生成图片

1、PrecessEngine类 作用是帮助我们可以快速得到各个Service接口并且可以生成activiti的工作环境 25张表的生成:

Service接口:作用:可以快速实现数据库25张表的操作

RepositeryService 关于部署相关的Service

RuntimeService 部署完了流程实例启动用到的Service

TaskService 当你启动对于每个不同的任务的Serivce

MistoryService

2、BPMN的ActivitiDesigner插件

IDEA工具中安装ActivitiDesigner的注意细节

3、做出流程定义图

4、部署流程定义:

方式一、单个文件(bpmn文件,png文件)

方式二、先将bpmn文件,png文件压缩成Zip文件,但是activiti最终也是以单文件形式保存,说明activiti进行了解压工作。

5、启动流程实例

RuntimeService

StartProcessInstanceByKey("key")

6、查看任务

TaskService taskService.createTaskQuery()

7、完成任务

TaskService 主要使用到taskService.complete("任务ID");来执行

//25张表的生成
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println(processEngine);

4.1、流程定义部署(方式一):

/*
    流程定义的部署
    activiti表有哪些?
    act_re_deployment 部署信息
    act_re_procdef 流程定义的一些信息
    act_re_bytearray 流程定义的bpmn文件及png文件
    运行后可到以上的表中看变化
 */
public class ActivitiDeployment {
    //流程定义部署
    public static void main(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、进行部署
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday.bpmn")//添加bpmn资源
                .addClasspathResource("diagram/holiday.png")
                .name("请假流程")
                .deploy();//添加png资源(图片)

        //4、输出部署的一些信息
        System.out.println("流程名称:" + deployment.getName() + " Id; " + deployment.getId());
    }

}

使用zip包来部署(方式二)

将holiday.bpmn 和 holiday.png 文件压缩成zip包。

/*
    使用Zip压缩包的格式来部署流程定义
    activiti表有哪些?
    act_re_deployment 部署信息
    act_re_procdef 流程定义的一些信息
    act_re_bytearray 流程定义的bpmn文件及png文件
 */
public class ActivitiDeployment {
    //流程定义部署
    public static void main(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、转化ZiPInputStream流对象
        InputStream is = ActivitiDeployment.class.getClassLoader().getResourceAsStream("diagram/holidayBpmn.zip");

        //将inputStream流转化为ZipInputStream流
        ZipInputStream zipInputStream = new ZipInputStream(is);

        //4、进行部署
        Deployment deployment = repositoryService.createDeployment()
                .addZipInputStream(zipInputStream)//添加bpmn资源
                .name("请假流程")
                .deploy();//添加png资源(图片)

        //4、输出部署的一些信息
        System.out.println("流程名称:" + deployment.getName() + "\nId; " + deployment.getId());
    }

}

5.1、启动流程实例

/*
    启动流程实例: 前提是先已经完成流程定义的部署工作
 */
public class ActivitiStartInstance {
    public static void main(String[] args) {
        //1、得到ProcessEnging对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RenService对象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //3、创建流程实例
        //ByKey是act_re_procdef表中的Key
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_1");

        //4、输出实例的相关信息
        System.out.println("流程部署ID:" + processInstance.getDeploymentId());
        System.out.println("流程实例ID:" + processInstance.getId());
        System.out.println("活动ID:" + processInstance.getActivityId());
    }

6.1、查询当前用户的任务列表


/*
    查询当前用户的任务列表(可根据某人名称来查)
 */
public class ActivitiTaskQuery {

    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、根据定义的key,负责人assignee来实现当前用户的任务列表查询
        //根据某人的名称来查询某人待处理的任务zhangsan,该名称在表act_ru_task中,ASSIGNEE列
        List<Task> tasks = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("zhangsan")
                .list();

        //4、任务列表的展示
        for (Task task : tasks) {
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务负责人ID:" + task.getAssignee());
            System.out.println("任务名称:" + task.getName());
        }

    }
}

7.1、处理任务

/*
    处理任务
    背后操作的表有:
        act_hi_avtinst  已完成的活动信息
        act_hi_identitylink 参与者信息
        act_hi_taskinsk 任务实例
        任务实例使用过程:
            (一个任务被执行一次之后就会添加一条数据用于执行下个任务,如果没有下一个任务了自然也就不会再添加了,执行方式:taskService.complete("填的是该表的ID(任务ID)");)
        act_ru_execution  执行表
        act_ru_identitylink  参与者信息
        act_ru_task 任务
 */
public class ActivitiCompleteTask {
    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、处理任务,结合当前任务列表的查询操作的话,任务ID:2505
        taskService.complete("7502");



    }
}

7.2、查询出任务直接处理掉

/*
    查询来任务直接处理掉
    背后操作的表有:
        act_hi_avtinst  已完成的活动信息
        act_hi_identitylink 参与者信息
        act_hi_taskinsk 任务实例
        任务实例使用过程:
            (一个任务被执行一次之后就会添加一条数据用于执行下个任务,如果没有下一个任务了自然也就不会再添加了,执行方式:taskService.complete("填的是该表的ID");)
        act_ru_execution  执行表
        act_ru_identitylink  参与者信息
        act_ru_task 任务
 */
public class ActivitiCompleteTask {
    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、查询出当前用户的任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("wangwu")
                .singleResult();//如果是查出多条任务的就不可使用singleResult()方法来了,就要使用list()

        //4、处理任务,结合当前任务列表的查询操作的话,任务ID:task.getId()
        taskService.complete(task.getId());



    }
}

删除已被部署的流程定义:

/*
    删除已经部署的流程定义
    背后影响的表:
        act_ge_bytearray
        act_re_deployment
        act_re_procdef
 */
public class DeleteProcessDefinition {
    /**
     * 注意事项
     *  1、当我们正在执行的这一套流程没有完成审批结束的时候,此时如果要删除流程定义信息就会失败
     *  2、如果公司层面要强制性删除,可以使用repositoryService.deleteDeployment("1",true);
     *  //参数true代表级联删除,此时就会先删除没有完成的流程结点,最后就可以删除流程定义信息,false的值代表不级联
     * @param args
     */

    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、创建RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、执行删除流程定义, 参数代表流程部署的id
        repositoryService.deleteDeployment("1");
        //repositoryService.deleteDeployment("1", true);//强制删除
    }
}

/*
    查询流程定义信息
 */
public class QueryProcessDefinition {

    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、创建RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、得到ProcessDefinition对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

        //4、设置条件,并查询出当前的所有流程定义  查询条件:流程定义的Key=请假申请流程
        //orderByProcessDefinitionVersion()设置排序方式,根据流程定义的版本号进行排序
        List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("请假申请流程")
                .orderByProcessDefinitionVersion()
                .desc().list();

        //5、输出流程定义信息
        for (ProcessDefinition processDefinition : definitionList) {
            System.out.println("流程定义ID:" + processDefinition.getId());
            System.out.println("流程定义名称:" + processDefinition.getName());
            System.out.println("流程定义的Key:" + processDefinition.getKey());
            System.out.println("流程定义的版本号:" + processDefinition.getVersion());
            System.out.println("流程部署的ID:" + processDefinition.getDeploymentId());

        }
    }
}

导入依赖

<!--文件的读写操作-->
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>

将bpmn和png文件读取到目标文件夹下:

/**
 * 需求:
 * 1、从Activiti的act_ge_bytearray表中读取两个资源文件
 * 2、将连个资源文件保存到路径: D:\Program\Y2\Maven\activiti资料
 *
 * 技术方案:
 *  1、第一种方式使用actviti的api来实现
 *  2、第二种方式:其实就是原理层面,可以使用jdbc的对blob类型,clob类型数据的读取,并保存
 *  3、IO流转换,最好使用commons-io.jar包可以轻松解决(当下使用这个)
 *
 * 真实应用场景:用户想查看这个请假流程具体哪些步骤要走?
 */
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、设置查询条件
        processDefinitionQuery.processDefinitionKey("请假申请流程");//参数流程定义的Key

        //5、执行查询操作,查询出想要的流程定义
        ProcessDefinition processDefinition = processDefinitionQuery.singleResult();

        //6、通过流程定义信息,得到部署ID
        String deploymentId = processDefinition.getDeploymentId();

        //7、通过repositoryService的方法,实现读取图片信息bpmn文件信息(输入流)
        //getResourceAsStream()方法的参数说明:第一个参数部署ID,第二个参数代表资源名称(图片资源的名称)
        //processDefinition.getDiagramResourceName()代表获取png图片资源的名称
        InputStream pngIs = repositoryService.
                getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
        InputStream bpmnIs = repositoryService.
                //processDefinition.getResourceName()代表获取bpmn文件的名称
                getResourceAsStream(deploymentId, processDefinition.getResourceName());

        //8、构建出OutputSteam流
        OutputStream pngOs =
                new FileOutputStream("D:/Program/Y2/Maven/activiti资料/"
                        + processDefinition.getDiagramResourceName());

        OutputStream bpmnOs =
                new FileOutputStream("D:/Program/Y2/Maven/activiti资料/"
                        + processDefinition.getResourceName());


        //9、输入流,输出流的转换 现在就是用到commons-io-xx.jar中的方法
        IOUtils.copy(pngIs,pngOs);
        IOUtils.copy(bpmnIs,bpmnOs);

        //10、关闭流
        pngOs.close();
        bpmnOs.close();
        pngIs.close();
        bpmnIs.close();
    }
}

历史数据的查看

/**
 * 需求:
 *  历史数据的查看
 */
public class HistoryQuery {

    public static void main(String[] args) throws IOException {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RepositoryService对象
        HistoryService historyService = processEngine.getHistoryService();

        //3、得到HistoricActivitiInstanceQuery对象
        HistoricActivityInstanceQuery historicActivityInstanceQuery =
                historyService.createHistoricActivityInstanceQuery();

        historicActivityInstanceQuery.processInstanceId("2501");

        //4、执行查询
        //orderByHistoricActivityInstanceStartTime().asc()加入这个可排序
        List<HistoricActivityInstance> list = historicActivityInstanceQuery.orderByHistoricActivityInstanceStartTime().asc().list();

        //5、遍历查询结果
        for (HistoricActivityInstance instance : list) {

            System.out.println(instance.getActivityId());
            System.out.println(instance.getActivityName());
            System.out.println(instance.getProcessDefinitionId());
            System.out.println(instance.getProcessInstanceId());
            System.out.println("===================");

        }

    }

流程定义总结回顾:

业务系统与activiti的整合开发的原理:

将流程与自己创建的表关联起来:

/**
 * 自动流程实例,添加进businessKey
 *
 * 本质:act_ru_execution表中的businessKey的字段要存入业务标识
     运行起来后可以到表act_ru_execution看变化
 */
public class BusinessKeyAdd {

    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService对象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //3、启动流程实例,同时还要指定业务标识businessKey,它本身就是请假单的id
        //第一个参数:是指流程定义key
        //第二个参数:是指业务标识businessKey
        ProcessInstance processInstance =
                runtimeService.startProcessInstanceByKey("请假申请流程","1001");

        //4、输出processInstance相关的属性,.getBusinessKey()拿到表act_ru_execution中的BusinessKey值
        System.out.println(processInstance.getBusinessKey());



    }
}

流程实例的状态(激活/挂起)

1、全部流程实例的挂起与激活

/**
 * 全部流程实例的挂起与激活
 **/
public class SuspendProcessInstance {

    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、查询流程实例
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("请假申请流程").singleResult();

        //4、得到当前流程定义的实例是否部为暂停状态
        boolean suspend = processDefinition.isSuspended();

        String id = processDefinition.getId();
        //5、判断
        if (suspend){
            //说明是暂停,就可以激活操作
            repositoryService.activateProcessDefinitionById(id, true, null);

            System.out.println("实例:" + id + "激活");
        }else {
            //否则挂起
            repositoryService.suspendProcessDefinitionById(id, true, null);
            System.out.println("实例:" + id + "挂起");
        }

    }
}

2、单个流程实例的挂起与激活

/**
 * 单个流程实例的挂起与激活
 **/
public class SuspendProcessInstance2 {

    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService对象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //3、查询流程实例
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceBusinessKey("1001").singleResult();
        //processInstanceId("2501")都可以

        //4、得到当前流程定义的实例是否部为暂停状态
        boolean suspended = processInstance.isSuspended();


        String id = processInstance.getId();
        //5、判断
        if (suspended){
            //说明是暂停,就可以激活操作
            runtimeService.activateProcessInstanceById(id);

            System.out.println("流程实例:" + id + "激活");
        }else {
            //否则挂起
            runtimeService.suspendProcessInstanceById(id);
            System.out.println("流程定义:" + id + "挂起");
        }

    }

挂起之后,如果还继续执行就会activitiExeption报错;

UEL表达式:

是其值不是固定的${value}

设置流程变量:

注意${value}中的值要和map中的value值要对应上

然后从新部署,再运行下列代码

启动流程实例,动态设置assignee

/**
 * 启动流程实例,动态设置assignee
 *
 */
public class AssigneeUEL {
    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService对象
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //3、设置assignee的取值,用户可以在界面上设置流程额执行人
        Map<String, Object> map = new HashMap<>();
        map.put("assginee0","wangwu");
        map.put("assginee1","zhangsan");
        map.put("assginee2","lisi");

        //4、启动流程实例,同时还要设置流程定义的assignee的值
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday2", map);

        //5、输出
        System.out.println(processEngine.getName());


    }
}

监听器分配

holiday3

选择任务监听器的类

判断下人物是否有任务,有再做完成任务

流程变量

比如:请假小于三天直接就部门经理审批就可以了,如果是大于三天的那再需要总经理审批再交到人事存档里。

流程变量可以使用的类型有:

流程变量 的作用域

现在就要做一个这样的示例:

先创建好流程图:

 

Holuday类:

注意:这里必须实现Serializable 接口

/**
 * 请假实体类
 *  注意pojo类型,一定要实现Serializable接口,否则在存储这个pojo时就会报异常
 */
public class Holiday implements Serializable {
    private Integer id;
    private String holidayName; //申请人的名称
    private Date beginDate; //开始时间
    private Date endDate; //结束时间
    private Float num; //请假天数
    private String reason; //事由
    private String type; //请假类型

    //get、set
}

VariableTest:

/**
 * 流程变量的测试
 */
public class VariableTest {

    //3、完成任务 zhangsan  ---> lisi ---> 判断流程变量的请假天数,1天 ---- 分支 : 人事经理存档
    public static void main(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService实例
        TaskService taskService = processEngine.getTaskService();

        //3、查询当前用户是否有任务
        String key = "myProcess_1";
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee("zhaoliu")
                .singleResult();

        //4、判断task != null, 说明当前有任务
        if (task != null) {
            taskService.complete(task.getId());
            System.out.println("任务执行完毕!");
        }

    }

    //2、启动流程实例
    //act_ge_bytearray
    //act_ru_variable观察这两张表中的变化
    /*public static void main(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService实例
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //3、流程定义的key问题, myProcess_1
        String key = "myProcess_1";
        Map<String, Object> map = new HashMap<>();

        Holiday holiday = new Holiday();
        holiday.setNum(1F);//这里先设置请假天数是1天,正常是直接走人事存档
        map.put("holiday", holiday);

        //4、启动流程实例,并且设置流程变量的值
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,map);

        //5、输出实例信息
        System.out.println(processInstance.getName());
        System.out.println(processInstance.getProcessDefinitionId());
    }*/

    //1、新的请假流程定义部署
    /*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/holiday4.bpmn")
                .addClasspathResource("diagram/holiday4.png")
                .name("请假流程-变量")
                .deploy();

        System.out.println(deploy.getId());
        System.out.println(deploy.getName());
    }*/
}

完成任务时设置变量的值:

//3、完成任务 zhangsan  ---> lisi ---> 判断流程变量的请假天数,1天 ---- 分支 : 人事经理存档
public static void main(String[] args) {
    //1、创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2、得到TaskService实例
    TaskService taskService = processEngine.getTaskService();

    //3、查询当前用户是否有任务
    String key = "myProcess_1";
    Task task = taskService.createTaskQuery()
            .processDefinitionKey(key)
            .taskAssignee("zhangsan")
            .singleResult();
    Map<String, Object> map = new HashMap<>();

    Holiday holiday = new Holiday();
    holiday.setNum(5F);
    map.put("holiday", holiday);

    //4、判断task != null, 说明当前有任务
    if (task != null) {
        taskService.complete(task.getId(), map);//完成任务时,设置流程变量的值
        System.out.println("任务执行完毕!");
    }

}

通过当前流程实例设置

通过流程实例id设置全局变量,该流程实例必须未执行完成。

1、新的请假流程定义部署

//1、新的请假流程定义部署
public static void main1(String[] args) {
    //1、创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2、得到RepositoryService实例
    RepositoryService repositoryService = processEngine.getRepositoryService();

    //3、部署
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("diagram/holiday4.bpmn")
            .addClasspathResource("diagram/holiday4.png")
            .name("请假流程-变量")
            .deploy();

    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

2、启动流程实例

//2、启动流程实例
//act_ge_bytearray
//act_ru_variable观察这两张表中的变化
public static void main2(String[] args) {
    //1、创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2、得到RuntimeService实例
    RuntimeService runtimeService = processEngine.getRuntimeService();

    //3、流程定义的key问题, myProcess_1
    String key = "myProcess_1";
    //Map<String, Object> map = new HashMap<>();
    //
    //Holiday holiday = new Holiday();
    //holiday.setNum(1F);
    //map.put("holiday", holiday);

    //4、启动流程实例,并且设置流程变量的值
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key);

    //5、输出实例信息
    System.out.println(processInstance.getName());
    System.out.println(processInstance.getProcessDefinitionId());
    System.out.println(processInstance.getId());


}

3、通过流程示例id,来测试流程变量

//新加入的:通过流程示例id,来测试流程变量
public static void main(String[] args) {
    //1、创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2、得到RuntimeService实例
    RuntimeService runtimeService = processEngine.getRuntimeService();

    //3、流程定义的key问题, myProcess_1
    String key = "myProcess_1";
    //Map<String, Object> map = new HashMap<>();

    Holiday holiday = new Holiday();
    holiday.setNum(5F);
    //map.put("holiday", holiday);

    //4、通过实例id,来设置流程变量
    //第一个参数:流程实例的id
    //第一个参数:流程变量名
    //第一个参数:流程变量名,所对应的值
    runtimeService.setVariable("2501","holiday", holiday);


    //4、启动流程实例,并且设置流程变量的值
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key);

    //5、输出实例信息
    System.out.println(processInstance.getName());
    System.out.println(processInstance.getProcessDefinitionId());
    System.out.println(processInstance.getId());

}

设置local流程变量

任务办理时设置local流程变量,当前运行的流程实例只能在该任务结束前使用,任务结束该变量无法在当前流程实例使用,可以通过查询历史任务查询。

说明:设置作用域为任务的local变量,每个任务可以设置同名的变量,互不影响。也就是只作用于当前节点,对下一节点是不影响的。

注意:

任务id必须是当前代办任务id,act_ru_task中存在。

设置候选人

现在开始代码的实现:

按1~7的顺序执行,看结果

/**
 *  组任务的测试
 */
public class GroupTest {

    //8、候选用户不想执行该任务,归还组任务
    //归还组任务,直接设置assignee为null就可以了
    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、设置一些参数,流程定义的key,候选用户
        String key = "holiday5";
        String candidate_users = "zhangsan";

        //4、执行查询
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskCandidateUser(candidate_users)//设置候选用户
                .singleResult();


        if (task != null){
            //如果要归还组任务,直接设置assignee为null就可以了
            taskService.setAssignee(task.getId(), null);
        }

    }
    //7、候选用户来执行任务
    public static void main7(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、设置一些参数,流程定义的key,候选用户
        String key = "holiday5";
        String candidate_users = "zhangsan";

        //4、执行查询
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskCandidateUser(candidate_users)//设置候选用户
                .singleResult();


        if (task != null){
            taskService.complete(task.getId());
            System.out.println("任务执行完毕!");

            //如果要归还组任务,直接设置assignee为null就可以了
            //taskService.setAssignee(task.getId(), null);
        }

    }

    //6、再次查询当前的用户查询自己的任务
    //看此这次的assignee是否有值了
    public static void main6(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、设置一些参数,流程定义的key,候选用户
        String key = "holiday5";
        String candidate_users = "zhangsan";

        //4、执行查询
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskCandidateUser(candidate_users)//设置候选用户
                .list();

        for (Task task : list) {
            System.out.println(task.getProcessInstanceId());
            System.out.println(task.getId());
            System.out.println(task.getName());
            System.out.println(task.getAssignee());//为null,说明当前的zhangsan只是一个候选人,并不是任务的执行人

        }

    }

    //5、测试zhangsan拾取组任务
    //拾取任务的过程是将候选用户转化为真正的任务的负责人(让任务的assignee有值)
    public static void main5(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、设置一些参数,流程定义的key,候选用户
        String key = "holiday5";
        String candidate_users = "zhangsan";

        //4、执行查询
        Task task = taskService.createTaskQuery()
                .processDefinitionKey(key)
                .taskCandidateUser(candidate_users)//设置候选用户
                .singleResult();

        //5、判断
        if (task != null) {
            //拾取任务,给任务表中的assignee字段赋值
            taskService.claim(task.getId(), candidate_users);//第二个参数任务ID,第二个参数为候选用户名
            System.out.println("任务拾取完毕!");
        }
    }

    //4、查询候选用户的组任务
    public static void main4(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、设置一些参数,流程定义的key,候选用户
        String key = "holiday5";
        String candidate_users = "zhangsan";

        //4、执行查询
        List<Task> list = taskService.createTaskQuery().processDefinitionKey(key)
                .taskCandidateUser(candidate_users)
                .list();

        //5、输出
        for (Task task : list) {
            System.out.println(task.getProcessInstanceId());
            System.out.println(task.getId());
            System.out.println(task.getName());
            System.out.println(task.getAssignee());//为null,说明当前的zhangsan只是一个候选人,并不是任务的执行人
        }

    }

    //3、填写请假单的任务要执行完成
    //执行完这个方法后可到,任务表里观察assignee字段,现在这里的值是null的,等拾取之后才会有值
    public static void main3(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、查询出当前用户的任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("holiday5")
                .taskAssignee("zhangsan")
                .singleResult();//如果是查出多条任务的就不可使用singleResult()方法来了,就要使用list()

        //4、处理任务,结合当前任务列表的查询操作的话,任务ID:task.getId()
        if (task != null) {
            taskService.complete(task.getId());
            System.out.println("任务执行完毕");
        }
    }

    //2、启动流程实例
    public static void main2(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService实例
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //3、启动流程实例,流程定义的key需要知道holiday
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday5");

        //4、输出实例信息
        System.out.println(processInstance.getName());
        System.out.println(processInstance.getProcessDefinitionId());
        System.out.println(processInstance.getId());

    }


    //1、流程部署
    public static void main1(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday5.bpmn")
                //.addClasspathResource("diagram/holiday4.png")
                .name("请假流程-候选人")
                .deploy();

        //4、获取部署一些信息
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());

    }
}

任务交接

任务交接,任务负责人将任务交给其它候选人办理该任务

//9、任务交接,前提要保证当前用户是这个任务的负责人,这时候他才可以有权限去将任务交接给其他候选人
//也是相当于给act_ru_task表中Assignee赋值
public static void main(String[] args) {
    //1、得到ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2、得到TaskService对象
    TaskService taskService = processEngine.getTaskService();

    //3、设置一些参数,流程定义的key,候选用户
    String key = "holiday5";
    String candidate_users = "zhangsan";

    //4、执行查询
    Task task = taskService.createTaskQuery()
            .processDefinitionKey(key)
            .taskCandidateUser(candidate_users)//设置候选用户
            .singleResult();


    //5、判断是否有这个任务
    if (task != null) {
        taskService.setAssignee(task.getId(), "lisi");//交接任务 ,交接任务就是一个候选人拾取任务用户的过程
        System.out.println("交接任务完成!");
    }
}

网关

1、排他网关

用来在流程中实现决策,当流程执行到这个网关,所有分支都会判断条件是否为true,如果为true则执行该分支。

注意:排他网关只会选择一个为true的分支执行。(即使两个分支条件都为true,排他网关也会只选择一条分支去执行)。其也可以实现分支

如果没有使用排他网关,但两个条件都成立的便会报错,ExclusiveGateWayTest01类就是用来测试没加排他网关时的情况,这里就不演示了,好奇的话可以让两个条件都成立去运行看看

/**
 *  测试排他网关
 *      1、测试没有网关时的情况
 *          两个分支条件:holiday.num >=1
 *                      holiday.num >3
 */
public class ExclusiveGateWayTest02 {
    //3、填写请假单的任务要执行完成
    //执行完这个方法后可到,任务表里观察assignee字段,现在这里的值是null的,等拾取之后才会有值
    public static void main3(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、查询出当前用户的任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("zhaoliu")
                .singleResult();//如果是查出多条任务的就不可使用singleResult()方法来了,就要使用list()

        //完成任务的时候赋值
        //Holiday holiday = new Holiday();
        //holiday.setNum(2F);
        //Map<String, Object> map = new HashMap<>();
        //map.put("holiday", holiday);
        //4、处理任务,结合当前任务列表的查询操作的话,任务ID:task.getId()
        if (task != null) {
            taskService.complete(task.getId());
            //taskService.complete(task.getId(),map);
            System.out.println("任务执行完毕");
        }
    }

    //2、启动流程实例
    public static void main2(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService实例
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //启动流程的时候赋值
        Holiday holiday = new Holiday();
        holiday.setNum(5F);
        Map<String, Object> map = new HashMap<>();
        map.put("holiday", holiday);


        //3、启动流程实例,流程定义的key需要知道holiday
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_1",map);

        //4、输出实例信息
        //System.out.println(processInstance.getName());
        System.out.println("流程定义ID" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例ID" + processInstance.getId());

    }


    //1、流程部署
    public static void main1(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("diagram/activiti05/holiday5.bpmn")
                //.addClasspathResource("diagram/holiday4.png")
                .name("请假流程-排他网关")
                .deploy();

        //4、获取部署一些信息
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());

    }
}

并行网关

 

测试跟上一个测试一样的,看着任务人执行即可看到效果

只要观察act_ru_task和act_hi_actinst表的数据

/**
 *  测试并行网关
 *      只要丰富了我们的请假流程
 *
 */
public class ParallelGateWayTest {

    //3、填写请假单的任务要执行完成
    //执行完这个方法后可到,任务表里观察assignee字段,现在这里的值是null的,等拾取之后才会有值
    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、查询出当前用户的任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("xiaomao")
                .singleResult();//如果是查出多条任务的就不可使用singleResult()方法来了,就要使用list()

        //完成任务的时候赋值
        //Holiday holiday = new Holiday();
        //holiday.setNum(2F);
        //Map<String, Object> map = new HashMap<>();
        //map.put("holiday", holiday);
        //4、处理任务,结合当前任务列表的查询操作的话,任务ID:task.getId()
        if (task != null) {
            taskService.complete(task.getId());
            //taskService.complete(task.getId(),map);
            System.out.println("任务执行完毕");
        }
    }

    //2、启动流程实例
    public static void main2(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService实例
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //启动流程的时候赋值
        Holiday holiday = new Holiday();
        holiday.setNum(5F);
        Map<String, Object> map = new HashMap<>();
        map.put("holiday", holiday);


        //3、启动流程实例,流程定义的key需要知道holiday
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_1",map);

        //4、输出实例信息
        //System.out.println(processInstance.getName());
        System.out.println("流程定义ID" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例ID" + processInstance.getId());

    }


    //1、流程部署定义,带排他网关,同时还带并行网关
    public static void main1(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("diagram/activiti05/holiday5.bpmn")
                //.addClasspathResource("diagram/holiday4.png")
                .name("请假流程-并行网关")
                .deploy();

        //4、获取部署一些信息
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());

    }
}

包含网关

/**
 *  测试包含网关
 *      特点:具有排他网关和并行网关的一些共同点
 *          可以设置流程变量,当流程变量取值都成立时,此时若干个分支都可以执行
 *
 */
public class InclusiveGateWayTest {

    //3、填写请假单的任务要执行完成
    //执行完这个方法后可到,任务表里观察assignee字段,现在这里的值是null的,等拾取之后才会有值
    public static void main(String[] args) {
        //1、得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到TaskService对象
        TaskService taskService = processEngine.getTaskService();

        //3、查询出当前用户的任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")
                .taskAssignee("xiaowang")
                .singleResult();//如果是查出多条任务的就不可使用singleResult()方法来了,就要使用list()

        //完成任务的时候赋值
        //Holiday holiday = new Holiday();
        //holiday.setNum(2F);
        //Map<String, Object> map = new HashMap<>();
        //map.put("holiday", holiday);
        //4、处理任务,结合当前任务列表的查询操作的话,任务ID:task.getId()
        if (task != null) {
            taskService.complete(task.getId());
            //taskService.complete(task.getId(),map);
            System.out.println("任务执行完毕");
        }
    }

    //2、启动流程实例
    public static void main2(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RuntimeService实例
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //启动流程的时候赋值
        Integer userType = 2;//代表管理者

        Map<String, Object> map = new HashMap<>();
        map.put("userType", userType);

        //3、启动流程实例,流程定义的key需要知道holiday
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_1",map);

        //4、输出实例信息
        //System.out.println(processInstance.getName());
        System.out.println("流程定义ID" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例ID" + processInstance.getId());

    }


    //1、流程部署定义,带排他网关,同时还带并行网关
    public static void main1(String[] args) {
        //1、创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3、部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("diagram/activiti05/examine.bpmn")
                //.addClasspathResource("diagram/holiday4.png")
                .name("体检流程-包含网关")
                .deploy();

        //4、获取部署一些信息
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伽高

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值