文档章节

Activiti5使用

xiaozhou18
 xiaozhou18
发布于 2017/06/17 17:50
字数 3715
阅读 154
收藏 4
点赞 1
评论 0

一、Activiti 的 25 张表的两种创建方式

/**
     * 生成Activiti需要的25表
     */
    @Test
    public void testCreateTable(){
ProcessEngineConfiguration pec=ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(); // 获取流程引擎配置
        pec.setJdbcDriver("com.mysql.jdbc.Driver"); // 配置驱动
        pec.setJdbcUrl("jdbc:mysql://localhost:3306/db_activiti"); // 配置连接地址
        pec.setJdbcUsername("root"); // 用户名
        pec.setJdbcPassword("root"); // 密码
        /**
         * 配置模式  true 自动创建和更新表
         */
        pec.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        
        // 获取流程引擎对象
        ProcessEngine pe=pec.buildProcessEngine(); 
    }
    
    /**
     * 生成Activiti需要的25表 使用配置文件
     */

在resources下新建一个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"
xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db_activiti" />
    <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
    <property name="jdbcUsername" value="root" />
    <property name="jdbcPassword" value="root" />
    <property name="databaseSchemaUpdate" value="true" />
  </bean>
</beans>
    @Test
    public void testCreateTableWithXml(){
         // 引擎配置
ProcessEngineConfiguration pec=ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        // 获取流程引擎对象
        ProcessEngine processEngine=pec.buildProcessEngine();
    }

二、在 Eclipse 上安装 Activiti 插件

1、 Help → Install New Software→Add.

2、Name:Activiti BPMN 2.0 designer

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

这个要勾选上  否则创建图片不能保存

三、第一个activiti 程序

public class HelloWorldProcess {

    /**
     * 获取默认流程引擎实例,会自动读取activiti.cfg.xml文件
     */
    private ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
    

部署流程定义


    /**
     * 部署流程定义
     */
    @Test
    public void deploy(){
        Deployment deployment=processEngine.getRepositoryService() // 获取部署相关Service
                .createDeployment() // 创建部署
                .addClasspathResource("diagrams/HelloWorld.bpmn") // 加载资源文件
                .addClasspathResource("diagrams/HelloWorld.png") // 加载资源文件
                .name("HelloWorld流程") // 流程名称
                .deploy(); // 部署
        System.out.println("流程部署ID:"+deployment.getId()); 
        System.out.println("流程部署Name:"+deployment.getName());
    }
    

启动流程实例


    /**
     * 启动流程实例
     */
    @Test
    public void start(){
        ProcessInstance pi=processEngine.getRuntimeService() // 运行时Service

//  .startProcessInstanceByKey("myFirstProcess"  "变量是一个map集合")  流程启动的时候就设置个变量         相 当于用 processEngine.getRuntimeService().setVariable(taskId, "date", new Date()) 相当于给这个流程初始化数据
            .startProcessInstanceByKey("myFirstProcess"); // 流程定义 act_re_procdef表的KEY字段值
        System.out.println("流程实例ID:"+pi.getId());
        System.out.println("流程定义ID:"+pi.getProcessDefinitionId()); 
    }
    

查看任务


    /**
     * 查看任务
     */
    @Test
    public void findTask(){
        List<Task> taskList=processEngine.getTaskService() // 任务相关Service
            .createTaskQuery() // 创建任务查询
            .taskAssignee("java1234_小锋") // 指定某个人  act_ru_task这个表里的 assignee_字段
            .list();
        for(Task task:taskList){
            System.out.println("任务ID:"+task.getId()); 
            System.out.println("任务名称:"+task.getName());
            System.out.println("任务创建时间:"+task.getCreateTime());
            System.out.println("任务委派人:"+task.getAssignee());
            System.out.println("流程实例ID:"+task.getProcessInstanceId());
        }
    }
    

完成任务


    /**
     * 完成任务
     */
    @Test
    public void completeTask(){
        processEngine.getTaskService() // 任务相关Service
            .complete("30004"); //30004表示正在运行的任务id     task.getId()   表里的act_ru_task id_字段
    }

查询流程定义

  

/**
     * 查询流程定义 返回流程定义集合  对应表 act_re_procdef
     */
    @Test
    public void list(){
        String processDefinitionKey="myFirstProcess";
        List<ProcessDefinition> pdList=processEngine.getRepositoryService() // 获取service
            .createProcessDefinitionQuery() // 创建流程定义查询
            .processDefinitionKey(processDefinitionKey) // 通过key查询  act_re_procdef 表里的key_字段
            .list();  // 返回一个集合
        for(ProcessDefinition pd:pdList){
            System.out.println("ID_"+pd.getId());
            System.out.println("NAME_"+pd.getName());
            System.out.println("KEY_"+pd.getKey());
            System.out.println("VERSION_"+pd.getVersion());
            System.out.println("=========");
        }
    }

通过ID查询某个流程定义

 

/**
     * 通过ID查询某个流程定义
     */
    @Test
    public void getById(){
        String processDefinitionId="myFirstProcess:2:7504";
        ProcessDefinition pd=processEngine.getRepositoryService() // 获取service
            .createProcessDefinitionQuery() // 创建流程定义查询
            .processDefinitionId(processDefinitionId) // 通过id查询  act_re_procdef 中的 id_字段
            .singleResult();
        System.out.println("ID_"+pd.getId());
        System.out.println("NAME_"+pd.getName());
        System.out.println("KEY_"+pd.getKey());
        System.out.println("VERSION_"+pd.getVersion());
            
    }

查询最新版本的流程定义

 

//查询最新版本的流程定义
    @Test
    public void queryPng(){
        RepositoryService service = engine.getRepositoryService();
        List<ProcessDefinition> version = service.createProcessDefinitionQuery().latestVersion().list();
        for (ProcessDefinition processDefinition : version) {
            System.out.println(processDefinition.getName());
        }
    }

/**
     * 根据流程部署id和资源文件名称来查询流程图片
     * @throws Exception
     */
    @Test
    public void getImageById()throws Exception{
        InputStream inputStream=processEngine.getRepositoryService() // 获取sevice
            .getResourceAsStream("10001", "helloWorld/HelloWorld.png");
        FileUtils.copyInputStreamToFile(inputStream,new File("c:/helloWorld.png"));
    }

/**
     * 查询最新版本的流程定义
     * @throws Exception
     */
    @Test
    public void listLastVersion()throws Exception{

        List<ProcessDefinition> listAll=processEngine.getRepositoryService() // 获取service
            .createProcessDefinitionQuery() // 创建流程定义查询
            .orderByProcessDefinitionVersion().asc() // 根据流程定义版本升序
            .list();  // 返回一个集合
        
        // 定义有序Map,相同的Key,假如添加map的值  后者的值会覆盖前面相同的key的值
        Map<String,ProcessDefinition> map=new LinkedHashMap<String,ProcessDefinition>();
        // 遍历集合,根据key来覆盖前面的值,来保证最新的key覆盖前面所有老的key的值
        for(ProcessDefinition pd:listAll){
            map.put(pd.getKey(), pd);
        }
        
        List<ProcessDefinition> pdList=new LinkedList<ProcessDefinition>(map.values());
        for(ProcessDefinition pd:pdList){
            System.out.println("ID_"+pd.getId());
            System.out.println("NAME_"+pd.getName());
            System.out.println("KEY_"+pd.getKey());
            System.out.println("VERSION_"+pd.getVersion());
            System.out.println("=========");
        }
    }

删除所有key相同的流程定义

 

/**
     * 删除所有key相同的流程定义
     * @throws Exception
     */
    @Test
    public void deleteByKey()throws Exception{
        String processDefinitionKey="helloWorld2";
        List<ProcessDefinition> pdList=processEngine.getRepositoryService() // 获取service
                .createProcessDefinitionQuery() // 创建流程定义查询
                .processDefinitionKey(processDefinitionKey) // 根据key查询
                .list();  // 返回一个集合
        for(ProcessDefinition pd:pdList){
            processEngine.getRepositoryService()//按照部署流程id删除   true表示级联删除
                .deleteDeployment(pd.getDeploymentId(),true);   act_re_deployment这个表的 id_  
        }

查询流程状态

/**
     * 查询流程状态(正在执行 or 已经执行结束)
     */
    @Test
    public void processState(){
        ProcessInstance pi=processEngine.getRuntimeService() // 获取运行时Service
            .createProcessInstanceQuery() // 创建流程实例查询
            .processInstanceId("35001") // 用流程实例id查询  act_ru_execution 表中的proc_inst_id_
            .singleResult();
        if(pi!=null){
            System.out.println("流程正在执行!");
        }else{
            System.out.println("流程已经执行结束!");
        }
    }

历史任务查询

    /**
     * 历史任务查询  在act_hi_taskinst表里    只有任务的节点 不包括开始节点和结束节点
     */
    @Test
    public void historyTaskList(){
        List<HistoricTaskInstance> list=processEngine.getHistoryService() // 历史相关Service
            .createHistoricTaskInstanceQuery() // 创建历史任务实例查询
            .processInstanceId("35001") // 用流程实例id查询  act_hi_taskinst 表里的proc_inst_id_ 字段
            .finished() // 查询已经完成的任务
            .list(); 
        for(HistoricTaskInstance hti:list){
            System.out.println("任务ID:"+hti.getId());
            System.out.println("流程实例ID:"+hti.getProcessInstanceId());
            System.out.println("任务名称:"+hti.getName());
            System.out.println("办理人:"+hti.getAssignee());
            System.out.println("开始时间:"+hti.getStartTime());
            System.out.println("结束时间:"+hti.getEndTime());
            System.out.println("=================================");
        }
    }

历史活动查询

 

/**
     * 历史活动查询  在act_hi_actinst表里  包括开始节点和结束节点
     */
    @Test
    public void historyActInstanceList(){
        List<HistoricActivityInstance>  list=processEngine.getHistoryService() // 历史相关Service
            .createHistoricActivityInstanceQuery() // 创建历史活动实例查询
            .processInstanceId("35001") // 执行流程实例id  act_hi_actinst里的proc_inst_id_ 字段
            .finished()  //unfinished表示没完成的
            .list();
        for(HistoricActivityInstance hai:list){
            System.out.println("活动ID:"+hai.getId());
            System.out.println("流程实例ID:"+hai.getProcessInstanceId());
            System.out.println("活动名称:"+hai.getActivityName());
            System.out.println("办理人:"+hai.getAssignee());
            System.out.println("开始时间:"+hai.getStartTime());
            System.out.println("结束时间:"+hai.getEndTime());
            System.out.println("=================================");
        }
    }

/**
     * 设置流程变量数据
     */
    @Test
    public void setVariableValues(){
        TaskService taskService=processEngine.getTaskService(); // 任务Service
        String taskId="72504";
        taskService.setVariable(taskId, "days", 2);
        // taskService.setVariable(taskId, "date", new Date());
        taskService.setVariableLocal(taskId,"date", new Date());
        taskService.setVariable(taskId, "reason", "发烧");
        Student student=new Student();
        student.setId(1);
        student.setName("张三");
        taskService.setVariable(taskId, "student", student); // 存序列化对象
    }
    
    /**
     * 获取流程变量数据
     */
    @Test
    public void getVariableValues(){
        TaskService taskService=processEngine.getTaskService(); // 任务Service
        String taskId="80002";
        Integer days=(Integer) taskService.getVariable(taskId, "days");
        // Date date=(Date) taskService.getVariable(taskId, "date");
        Date date=(Date) taskService.getVariableLocal(taskId, "date");
        String reason=(String) taskService.getVariable(taskId, "reason");
        Student student=(Student) taskService.getVariable(taskId, "student"); 
        System.out.println("请假天数:"+days);
        System.out.println("请假日期:"+date);
        System.out.println("请假原因:"+reason);
        System.out.println("请假对象:"+student.getId()+","+student.getName());
    }


    
    用TaskService 设置流程变量数据


    
    /**
     * 设置流程变量数据
     */
    @Test
    public void setVariableValue(){
        TaskService taskService=processEngine.getTaskService(); // 任务Service
        String taskId="60004";  //正在执行的任务id
        Student student=new Student(); //如果传递的是实体对象 该对象必须要实现序列化
        student.setId(1);
        student.setName("张三");

        Map<String, Object> variables=new HashMap<String,Object>();
        variables.put("days", 2);
        variables.put("date", new Date());
        variables.put("reason", "回家");
        variables.put("student", student);
        taskService.setVariables(taskId, variables);

//        service.setVariable(taskId, "days", 5);     一次可以设置一个变量 也可以把变量放到map集合里  设置变量
//        service.setVariable(taskId, "reason", "回家");
//        service.setVariable(taskId, "student", s);

        // service.setVariableLocal(taskId, "key", "value"); 设置局部变量 用的较少
    }

用TaskService获取流程变量数据


    
    /**
     * 获取流程变量数据
     */
    @Test
    public void getVariableValues(){
        TaskService taskService=processEngine.getTaskService(); // 任务Service
        String taskId="65002";
        Map<String,Object> variables=taskService.getVariables(taskId);
        Integer days=(Integer) variables.get("days");
        Date date=(Date) variables.get("date");
        String reason=(String) variables.get("reason");
        Student student=(Student)variables.get("student"); 

    //service.getVariableLocal(taskId, "key") 根据key获取局部变量 用的较少

//        Integer days = (Integer)service.getVariable(taskId, "days");
//        String reason = (String) service.getVariable(taskId, "reason");
//        Student student = (Student) service.getVariable(taskId, "student");

        System.out.println("请假天数:"+days);
        System.out.println("请假日期:"+date);
        System.out.println("请假原因:"+reason);
        System.out.println("请假对象:"+student.getId()+","+student.getName());
    }

  用RuntimeService 设置流程变量数据 流程启动的时候就可以设置变量和taskservice差不多

 

/**
     * 设置流程变量数据
     */
    @Test
    public void setVariableValues(){
        RuntimeService runtimeService=processEngine.getRuntimeService(); // 任务Service
        String executionId="90001";
        runtimeService.setVariable(executionId, "days", 2);
        runtimeService.setVariable(executionId, "date", new Date());
        runtimeService.setVariable(executionId, "reason", "发烧");
        Student student=new Student();
        student.setId(1);
        student.setName("张三");
        runtimeService.setVariable(executionId, "student", student); // 存序列化对象
    }


     用RuntimeService 获取流程变量数据  


    /**
     * 获取流程变量数据
     */
    @Test
    public void getVariableValues(){
        RuntimeService runtimeService=processEngine.getRuntimeService(); // 任务Service
        String executionId="90001";  //ac_ru_execution 表中的id_
        Integer days=(Integer) runtimeService.getVariable(executionId, "days");
        Date date=(Date) runtimeService.getVariable(executionId, "date");
        String reason=(String) runtimeService.getVariable(executionId, "reason");
        Student student=(Student) runtimeService.getVariable(executionId, "student"); 
        System.out.println("请假天数:"+days);
        System.out.println("请假日期:"+date);
        System.out.println("请假原因:"+reason);
        System.out.println("请假对象:"+student.getId()+","+student.getName());
    }

启动流程实例时设置变量

/**
     * 启动流程实例
     */
    @Test
    public void start(){
        Student student=new Student();
        student.setId(1);
        student.setName("张三");

        Map<String, Object> variables=new HashMap<String,Object>();
        variables.put("days", 2);
        variables.put("date", new Date());
        variables.put("reason", "回家");
        variables.put("student", student);
        
        ProcessInstance pi=processEngine.getRuntimeService() // 运行时Service
            .startProcessInstanceByKey("studentLevaeProcess", variables); // 启动流程的时候,设置流程变量

        System.out.println("流程实例ID:"+pi.getId());
        System.out.println("流程定义ID:"+pi.getProcessDefinitionId()); 
    }

完成任务的时候设置流程变量

/**
     * 完成任务
     */
    @Test
    public void completeTask(){

Student student=new Student();
        student.setId(1);
        student.setName("张三");

        Map<String, Object> variables=new HashMap<String,Object>();
        variables.put("days", 2);
        variables.put("date", new Date());
        variables.put("reason", "发烧");
        variables.put("student", student);
        processEngine.getTaskService() // 任务相关Service
            .complete("112504", variables); //完成任务的时候,设置流程变量
    }

}

四、流程部署加载的zip压缩包的方式

/**
     * 部署流程定义使用zip方式
     */
    public void deployWithZip(){
        InputStream inputStream=this.getClass() // 取得当前class对象
            .getClassLoader() // 获取类加载器
            .getResourceAsStream("diagrams/helloWorld.zip"); // 获取指定文件资源流
        
        ZipInputStream zipInputStream=new ZipInputStream(inputStream); // 实例化zip输入流
        Deployment deployment=processEngine.getRepositoryService() // 获取部署相关Service
                .createDeployment() // 创建部署
                .addZipInputStream(zipInputStream) // 添加zip输入流
                .name("HelloWorld流程") // 流程名称
                .deploy(); // 部署
        System.out.println("流程部署ID:"+deployment.getId()); 
        System.out.println("流程部署Name:"+deployment.getName());
    }

五、数据库表的变化

################################
# 部署流程定义涉及到的表

# 流程部署表
SELECT * FROM `act_re_deployment`

# 流程定义表
SELECT * FROM `act_re_procdef`

# 资源文件表
SELECT * FROM `act_ge_bytearray`

# 系统配置表 
SELECT * FROM `act_ge_property`

################################
# 启动流程实例涉及到的表

# 流程实例运行时 执行对象表
SELECT * FROM `act_ru_execution`

# 流程实例运行时 身份联系表
SELECT * FROM `act_ru_identitylink`

# 流程实例运行时 用户任务表
SELECT * FROM `act_ru_task`

# 活动节点历史表
SELECT * FROM `act_hi_actinst`

# 身份联系表 历史
SELECT * FROM `act_hi_identitylink`

# 流程实例表 历史
SELECT * FROM `act_hi_procinst`

# 历史任务表 
SELECT * FROM `act_hi_taskinst`

################################
# 结束流程实例涉及到的表
# 运行时  表数据全部清空
# 历史表  表数据修改 或者增加了数据


################################
# 设置流程变量涉及到的表

# 运行时流程变量表
SELECT * FROM `act_ru_variable`

# 历史流程变量表
SELECT * FROM `act_hi_varinst`

六、多种线路流程执行情况

连线

流程图如下

当请假天数小于10天班长审批完直接结束

当请假天数大于10天时班长审批完班主任审批完才能结束

流程线表达式如下

//完成任务
    @Test
    public void compelet(){
        TaskService service = engine.getTaskService();
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("days", 18);
        service.complete("105002",map); //在请假完成的时候带参数 或者设置一个全局变量 key的值一定要是days和表达式中的值要一致
    }

排它网关  排它网关和连线的区别  是排它网关如果没有匹配的条件时可以默认执行某条流程

流程图如下

当请假天数小于3天时班长审批

当请假天数大于3天小于7天班主任审批

当请假天数条件不满足前两个(也就是大于7天)的是校长审批

设置默认走校长审批  流程  配置如下   大于7天的那个条线是flow5   默认的flow5 这个一定不要设置大于几天的那个表达式 (condition) 因为前两个如果不满足的情况下回默认走flow5那个流程

做法和上面的连线是一样的  在请假完成的时候带参数 或者设置一个全局变量 key的值一定要是days和表达式中的值要一致

 

并行网关  并行网关 是多个流程一起走  当多个流程都走完时在继续向下执行

流程图如下

班长和班主任都审批通过后才可以在往下执行

七、用户和组的创建删除

创建用户

@Test
    public void testSaveUser(){
        IdentityService indentityService=processEngine.getIdentityService();
        User user=new UserEntity(); // 实例化用户实体  activiti提供的一个用户接口
        user.setId("wangwu");
        user.setPassword("123");
        user.setEmail("1234@qq.com");
        indentityService.saveUser(user); 
    }

删除用户

@Test
    public void testDeleteUser(){
        IdentityService indentityService=processEngine.getIdentityService();
        indentityService.deleteUser("wangwu"); //根据  act_id_user id_字段删除
    }

创建组

@Test
    public void testSaveGroup(){
        IdentityService indentityService=processEngine.getIdentityService();
        Group group=new GroupEntity();
        group.setId("test");
        indentityService.saveGroup(group); 
    }

删除组



    @Test
    public void testDeleteGroup(){
        IdentityService indentityService=processEngine.getIdentityService();
        indentityService.deleteGroup("test");   //根据  act_id_group id_字段删除
    }

把用户添加到组里


    @Test
    public void testSaveMembership(){
        IdentityService indentityService=processEngine.getIdentityService();
        indentityService.createMembership("wangwu", "test"); //第一个表示act_id_user中的id_字段第二个表示act_id_group中的id_字段
    }

删除用户和组的关联关系

@Test
    public void testDeleteMembership(){
        IdentityService indentityService=processEngine.getIdentityService();
        indentityService.deleteMembership("wangwu", "test");  /第一个表示act_id_user中的id_字段第二个表示act_id_group中的id_字段
    }

八、任务分配

个人任务分配

1、在流程图的Main config -> Assignee写个固定的值    (此方式不常用)

2、在启动或者完成任务的时候设置办理人  在配置表达式  如Main config -> Assignee    ${userId}

这种方式变量的key值一定要和assignee 配置的表达式的值一致

3、TaskListener 监听实现

新建一个类  实现 TaskListener接口  代码如下

public class MyTaskListener implements TaskListener{
    private static final long serialVersionUID = 1L;

    public void notify(DelegateTask delegateTask) {
        delegateTask.setAssignee("赵六"); // 指定办理人
    }

}

下图中的listeners中配置上  上面自定义的监听器类TaskListener   走到此流程的时候会执行这个类中notify方法的内容

多用户任务分配    只要是配置的多个用户其中的一个完成任务即可

1、在流程图的Main config -> Candidate users(comma speparated)写个固定的值    (此方式不常用)

在流程图中配置方式如下


    /**
     * 查看任务
     */
    @Test
    public void findTask(){
        List<Task> taskList=processEngine.getTaskService() // 任务相关Service
            .createTaskQuery() // 创建任务查询
            //.taskAssignee("李四") // 指定某个人
            .taskCandidateUser("赵六") // 指定候选人
            .list();
        for(Task task:taskList){
            System.out.println("任务ID:"+task.getId()); 
            System.out.println("任务名称:"+task.getName());
            System.out.println("任务创建时间:"+task.getCreateTime());
            System.out.println("任务委派人:"+task.getAssignee());
            System.out.println("流程实例ID:"+task.getProcessInstanceId());
        }
    }

2、在启动或者完成任务的时候设置办理人  在配置表达式  如Main config -> Candidate users(comma speparated)    ${userIds}

这种方式变量的key值一定要和Candidate users(comma speparated)配置的表达式的值一致

//完成任务
    @Test
    public void compelet(){
        TaskService service = engine.getTaskService();
        Map<String,Object> map=new HashMap<String, Object>();
        map.put("userIds", "bb,aa,cc"); //设置处理任务的候选人
        service.complete("247504",map);
    }

3、TaskListener 监听实现    和个人任务分配中的监听器一样

public class MyTaskListener implements TaskListener{
    private static final long serialVersionUID = 1L;

    public void notify(DelegateTask delegateTask) {
        // delegateTask.setAssignee("赵六"); // 指定办理人
        delegateTask.addCandidateUser("张三");
        delegateTask.addCandidateUser("李四");
        delegateTask.addCandidateUser("王五");
    }

}

组任务分配

租任务分配和个人 任务分配   多人任务分配是一样的

只要在这个组下的某一个用户都可以查看任务  并且处理任务

1、在流程图的Main config -> Candidate groups(comma speparated)写个固定的值    (此方式不常用)

配置如下

2、使用流程变量 Main config -> Candidate groups(comma speparated)

配置如下   这种方式变量的key值一定要和Candidate groups(comma speparated)配置的表达式的值一致

3、TaskListener 监听实现    和个人任务分配中的监听器一样

public void notify(DelegateTask delegateTask) {
        delegateTask.addCandidateGroup("1");
        delegateTask.addCandidateGroup("3");
    }

九、审批被打回来流程图

如果请假天数超过3天  班主任审批不给通过  这里用的是排他网关

© 著作权归作者所有

共有 人打赏支持
xiaozhou18
粉丝 2
博文 41
码字总数 87942
作品 0
哈尔滨
程序员
jBPM5与Activiti5比较

jBPM5与Activiti5比较 主要相似之处: 都是BPMN2过程建模和执行环境。都是BPM系统(符合BPM规范)。都是开源项目-遵循ASL协议( Apache的 软件许可)。都源自JBoss(Activiti5是jBPM4的衍生,...

不了了之
2012/11/07
0
1
activiti官网下载的6.0的包其中activiti5-engine-6.0.0.jar与activiti-engine-6.0.0.jar 配置信息有什么区别

最近在研究 activiti 6.0 版本 大家都知道6相对于5来说做了很大的改动,像之前活动对象 流程定义的pvm包,在6版本这全部删除了。所有我尝试写了几个demo,在我网上查找6版本所需要的配置时,发...

奋斗的少年ss
04/29
0
0
ACTIVITI5 事件监控类里的事务如何控制

activiti5 配置的事件监控类里面有数据库的处理,但是发现不能和工程的事务统一。已经配置的activiti5的事务,除了事件监控类里面的事务外,引擎其他事务和工程事务一致,但是配置的事件控制...

星忆
2013/07/12
2.5K
1
纵观jBPM:从jBPM3到jBPM5以及Activiti5

对jBPM来说,今年最大的事件莫过于jBPM的创建者Tom Baeyens离开JBoss了。Tom Baeyens离开的具体原因尚不清楚,但他的离开产生了两个结果:一是jBPM的下一个版本jBPM5完全放弃了jBPM4的基础代...

朱大
2011/08/16
0
0
activiti5 流程里面怎么回退到上一个节点???

activiti5 流程里面怎么回退到上一个节点??? 小白求教

徐率超
2014/04/19
6.2K
2
java开源流程框架技术选型

流程框架 技术选型 JBPM5 activiti5 OSWorkflow 选哪个?

光石头
2013/08/27
3.2K
14
activiti5.10 流程图乱码

activiti5在部署流程时,生成流程图中文出现乱码。 解决方案: 修改源码包中 ProcessDiagramCanvas.java 文件 130行, 将 Font font = new Font("Arial", 1, 11); g.setFont(font); 改为 Fo...

提广乾
2012/09/05
0
0
怎么样才能做到全面的事务管理?

最近在使用Activiti5,其中用到了它的TaskListener,即监听器,在监听器中写了一些对数据库的写入操作,这里我们暂且不谈这样设计是否存在问题,那我的问题是:如何对于在监听器中的数据库事务...

一条大河波浪宽
2013/11/17
204
3
Activiti简介

什么是工作流 工作流(Workflow),指“业务过程的部分或整体在计算机应用环境下的自动化”。是对工作流程及其各操作步骤之间业务规则的抽象、概括描述。 简单的说,流程就是多个人在一起合作...

科技小能手
2017/11/12
0
0
JEHC开源平台--JEHC

JEHC 开源平台,采用技术为: spring,springMVC,Mybatis,Activiti5,(Activiti 可视化设计器基于 IE,火狐,谷歌,360 等浏览器),Solr 4.10,MySQL,Netty,Redis,Ehcache,服务器监控...

dengcj123456
2017/05/11
6.2K
12

没有更多内容

加载失败,请刷新页面

加载更多

下一页

一款成功的全球服游戏该如何进行架构选型与设计?

全球服游戏如今正在成为出海游戏的主要考虑模式,跨国对战、全球通服打破国界的限制,将不同地区不同语言的玩家放在一起合作/竞技,成功吸引了大量玩家的关注,并逐渐成为主流的游戏玩法。 ...

UCloudTech
6分钟前
0
0
StringUtils类中isEmpty与isBlank的区别

org.apache.commons.lang.StringUtils类提供了String的常用操作,最为常用的判空有如下两种isEmpty(String str)和isBlank(String str)。 StringUtils.isEmpty(String str) 判断某字符串是否为...

说回答
18分钟前
0
0
react native使用redux快速上手

看例图 要求点击组件一中的按钮,改版组件二的背景色。 利用state和props和容易实现。 //app.jsimport React, {Component} from 'react';import {StyleSheet, Button, View, Text} from ...

燕归南
20分钟前
0
0
页面输出JSON格式数据

package com.sysware.utils;import java.io.IOException;import javax.servlet.ServletResponse;import org.apache.log4j.Logger;import com.sysware.SyswareConstant;pub......

AK灬
41分钟前
0
0
springCloud-2.搭建Eureka Client的使用

1.使用IDEA,Spring Initializr创建 2.填写项目资料 3.选择spring boot版本,插件选择Cloud Discovery→Eureka Discovery 4.选择保存地址 5.修改application.yml eureka: client: s...

贺小康
44分钟前
0
0
CenOS 6.5 RPM 安装 elasticsearch 6.3.1

下载 wget --no-check-certificate https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.1.rpm...

阿白
47分钟前
0
0
1.4 创建虚拟机&1.5 安装CentOS7&1.6 配置ip(上)&1.7 配置ip(下)

1.4 创建虚拟机 知识点 虚拟机网络链接模式 桥连 直接将虚拟网卡桥接到一个物理网卡上面。需要手工为虚拟系统配置IP地址、子网掩码,而且还要和宿主机器处于同一网段,这样虚拟系统才能和宿主...

小丑鱼00
53分钟前
0
0
TrustAsia(亚洲诚信)助力看雪2018安全开发者峰会

2018年7月21日,看雪2018安全开发者峰会在北京国家会议中心圆满落下帷幕。拥有18年悠久历史的老牌安全技术社区——看雪学院联手国内最大开发者社区CSDN,汇聚业内顶尖的安全开发者和技术专家...

亚洲诚信
55分钟前
0
0
Spring注解介绍

@Resource、@AutoWired、@Qualifier 都用来注入对象。其中@Resource可以以 name 或 type 方式注入,@AutoWired只能以 type 方式注入,@Qualifier 只能以 name 方式注入。 但它们有一些细微区...

lqlm
今天
0
0
32位汇编在64位Ubuntu上的汇编和连接

本教程使用的操作系统是Ubuntu Linux 18.04 LTS版本,汇编器是GNU AS(简称as),连接器是GNU LD(简称ld)。 以下是一段用于检测CPU品牌的汇编小程序(cpuid2.s): .section .dataoutput...

ryanliue
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部