Activiti6.0学习实践(5)-activiti流程引擎配置二

本节继续对activiti流程引擎的配置进行学习

1、EventLog配置

1.1、配置EventLog

首先在activiti_eventlog.cfg.xml中配置eventlog属性为true

Activiti6.0学习实践(5)-activiti流程引擎配置二_第1张图片

1.1.1测试代码

编写一个eventlog测试代码 ConfigEventLogTest.java

import org.activiti.engine.event.EventLogEntry;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/07
 */
public class ConfigEventLogTest {

    private static final Logger logger = LoggerFactory.getLogger(ConfigEventLogTest.class);

    //这里已经包含了流程引擎的创建
    @Rule
    public ActivitiRule activitiRule = new ActivitiRule("activiti_eventlog.cfg.xml");

    @Test
    @Deployment(resources = {"./my-process.bpmn20.xml"})
    public void configMDCTest1() {


        ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");

        List list = activitiRule.getTaskService().createTaskQuery().list();

        activitiRule.getTaskService().complete(list.get(0).getId());

        List eventLogEntries = activitiRule.getManagementService()
                .getEventLogEntriesByProcessInstanceId(processInstance.getProcessInstanceId());

        for (EventLogEntry eventLogEntry : eventLogEntries) {
            logger.info("eventlog.type= {}, eventlog.data ={}", eventLogEntry.getType().toString(), new String( eventLogEntry.getData()) );

        }
        logger.info("eventlogEntryies size={}", eventLogEntries.size());
    }

}

 

1.2 执行日志

执行日志情况如下:

Activiti6.0学习实践(5)-activiti流程引擎配置二_第2张图片

源码查看

在ProcessEngineConfigurationImpl.java类中有创建时间监听器的代码

Activiti6.0学习实践(5)-activiti流程引擎配置二_第3张图片

这里创建了一个新的EventLogger对象,这个对象是实现了一个监听器

Activiti6.0学习实践(5)-activiti流程引擎配置二_第4张图片

在这个类的初始化函数里面,设置了各种事件的监听处理类

Activiti6.0学习实践(5)-activiti流程引擎配置二_第5张图片

另外,当监听到事件后,调用 onEvent方法:

Activiti6.0学习实践(5)-activiti流程引擎配置二_第6张图片

 

2、 事件与监听器原理

Activiti6.0学习实践(5)-activiti流程引擎配置二_第7张图片

 

2.1 配置监听器

有三种类型的监听器

eventListeners:监听所有事件派发的通知

typedEventListeners:监听指定事件类型的通知

activiti:eventListener:只监听特定流程定义的事件

相关api对象:

ActivitiEvent 事件对象

ActivitiEventListener 监听器

ActivitiEventType 事件类型,是枚举类型,监听器针对具体的类型进行操作

2.2 通过eventListener监听事件

首先在配置文件中添加监听的配置

Activiti6.0学习实践(5)-activiti流程引擎配置二_第8张图片

生成一个事件监听类的具体实现ProcessEventListener.java

package com.study.activiti.event;

import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/09
 */
public class ProcessEventListener implements ActivitiEventListener {
   
    private static final Logger logger = LoggerFactory.getLogger(ProcessEventListener.class);
   

    @Override
    public void onEvent(ActivitiEvent event) {
        ActivitiEventType type = event.getType();
        if( ActivitiEventType.PROCESS_STARTED.equals( type)){
            logger.info("流程启动 {} \t 流程实例id={}", type, event.getProcessInstanceId());

        }
        if( ActivitiEventType.PROCESS_COMPLETED.equals( type)){
            logger.info("流程启动 {} \t 流程实例id={}", type, event.getProcessInstanceId());

        }

    }

    @Override
    public boolean isFailOnException() {
        return false;
    }
}

创建测试代码ConfigEventListenerTest

import com.study.activiti.event.CustomEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiActivityEventImpl;
import org.activiti.engine.event.EventLogEntry;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/07
 */
public class ConfigEventListenerTest {

    private static final Logger logger = LoggerFactory.getLogger(ConfigEventListenerTest.class);

    //这里已经包含了流程引擎的创建
    @Rule
    public ActivitiRule activitiRule = new ActivitiRule("activiti_eventListener.cfg.xml");

    @Test
    @Deployment(resources = {"./my-process.bpmn20.xml"})
    public void test1() {


        ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");

        List list = activitiRule.getTaskService().createTaskQuery().list();

        activitiRule.getTaskService().complete(list.get(0).getId());

        List eventLogEntries = activitiRule.getManagementService()
                .getEventLogEntriesByProcessInstanceId(processInstance.getProcessInstanceId());

        for (EventLogEntry eventLogEntry : eventLogEntries) {
            logger.info("eventlog.type= {}, eventlog.data ={}", eventLogEntry.getType().toString(), new String( eventLogEntry.getData()) );

        }
        logger.info("eventlogEntryies size={}", eventLogEntries.size());

       
    }


}

执行日志中会打印出来刚才监听实现中的打印信息

 

2.3 通过eventTypeListener监听事件

下面在上面基础上添加eventTpyeListener的功能。这个功能是通过监听指定类型的事件作出响应

创建针对指定类型的事件监听类ProcessEventTypeListener.java

package com.study.activiti.event;

import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/09
 */
public class ProcessEventTypeListener implements ActivitiEventListener {
   
    private static final Logger logger = LoggerFactory.getLogger(ProcessEventTypeListener.class);   

    @Override
    public void onEvent(ActivitiEvent event) {
        ActivitiEventType type = event.getType();
        if( ActivitiEventType.ACTIVITY_COMPLETED .equals( type)){
            logger.info("活动结束 {} \t 流程实例id={}", type, event.getProcessInstanceId());
        }  
    }

    @Override
    public boolean isFailOnException() {
        return false;
    }
}

在配置文件中添加对应的配置内容

Activiti6.0学习实践(5)-activiti流程引擎配置二_第9张图片

执行的时候,我们可以看到在原来的监听基础上,我们还多了事件类型的监听处理

Activiti6.0学习实践(5)-activiti流程引擎配置二_第10张图片

 

2.4 监听用户自定义事件

我们还可以进行用户自定义的监听,需要3个步骤:

首先添加一个事件监听的自定义处理

流程事件处理中dispatch一个自定义事件

在配置文件中添加这个事件的处理配置

下面我们看一下上面的三个步骤具体实现

  1. 创建一个类CustomEventListener.java
package com.study.activiti.event;

import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/09
 */
public class CustomEventListener implements ActivitiEventListener {
   
    private static final Logger logger = LoggerFactory.getLogger(CustomEventListener.class);
   

    @Override
    public void onEvent(ActivitiEvent event) {
        ActivitiEventType type = event.getType();
        if( ActivitiEventType.CUSTOM.equals( type)){
            logger.info("监听到用户事件 {} \t 流程实例id={}", type, event.getProcessInstanceId());
        }



    }

    @Override
    public boolean isFailOnException() {
        return false;
    }
}

2 修改流程处理中内容,在测试代码中添加下面语句

Activiti6.0学习实践(5)-activiti流程引擎配置二_第11张图片

3、修改配置文件

Activiti6.0学习实践(5)-activiti流程引擎配置二_第12张图片

最后我们看一下执行结果

Activiti6.0学习实践(5)-activiti流程引擎配置二_第13张图片

 

2.5 源码中事件监听的层级

Activiti6.0学习实践(5)-activiti流程引擎配置二_第14张图片

 

3、命令拦截器

 

​​​​​​​​​​​​​​3.1 创建一个拦截器

在下列位置创建一个拦截器

Activiti6.0学习实践(5)-activiti流程引擎配置二_第15张图片

这个类的代码如下:

package com.study.activiti.interceptor;

import org.activiti.engine.impl.interceptor.AbstractCommandInterceptor;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/13
 */
public class DurationCommandInterceptor  extends AbstractCommandInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(DurationCommandInterceptor.class);


    @Override
    public  T execute(CommandConfig config, Command command) {
        long  start = System.currentTimeMillis();

        try{
            return  this.getNext().execute(config, command);
        }finally{
            long  duration = System.currentTimeMillis()- start;
            logger.info("{} 执行时长 {} 毫秒", command.getClass().getSimpleName(), duration);
        }


    }
}

 

​​​​​​​3.2 创建配置文件:




    
         
          
        
        
            
                
            
        

    

    
           
           
          
          
          
          
          
    

    
    

3.3  ​​​​​​​创建测视类

创建一个测试类ConfigInterceptorTest.java

import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiActivityEventImpl;
import org.activiti.engine.event.EventLogEntry;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/07
 */
public class ConfigInterceptorTest {

    private static final Logger logger = LoggerFactory.getLogger(ConfigInterceptorTest.class);

    //这里已经包含了流程引擎的创建
    @Rule
    public ActivitiRule activitiRule = new ActivitiRule("activiti_interceptor.cfg.xml");

    @Test
    @Deployment(resources = {"./my-process.bpmn20.xml"})
    public void test1() {

        ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");

        List list = activitiRule.getTaskService().createTaskQuery().list();

        activitiRule.getTaskService().complete(list.get(0).getId());


   }

}

 ​​​​​​​3.4 执行结果

下图为执行日志

Activiti6.0学习实践(5)-activiti流程引擎配置二_第16张图片

 

​​​​​​​4、作业执行器

作业执行器的相关配置有:

作业执行器的配置

配置自定义线程池

流程定义定时启动配置

一些重要的配置参数:

asyncExecutorActivate 激活作业执行器,asyncExecutorXXX 异步执行配置,asyncExecutor, 一步执行器器bean

自定义线程池 ExecutorService:  corePoolSize核心线程数  maxPoolSize最大线程数

QueueCapacity:堵塞队列大小

Activiti6.0学习实践(5)-activiti流程引擎配置二_第17张图片

作业执行定时开始事件(Timer Start Event):

timeDate, 指定启动时间

timeDuration: 指定持续时间间隔后执行

timeCycle:指定周期执行

下面我们实现一个基于job的流程,并进行监听,打印job执行的相关信息

​​​​​​​4.1 创建一个定时执行流程定义文件

首先创建一个bpmc的xml文件





   


      
         
            R5/PT10S
         
      
      
     
      
      

      

   

 

​​​​​​​4.2 创建指定JOB监听器

创建一个只监听job的监听器:JobEventListener.java

package com.study.activiti.event;

import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/09
 */
public class JobEventListener implements ActivitiEventListener {
   
    private static final Logger logger = LoggerFactory.getLogger(JobEventListener.class);
   

    @Override
    public void onEvent(ActivitiEvent event) {
        ActivitiEventType type = event.getType();
        String name = type.name();

        if(  name.startsWith("TIMER") || name.startsWith("JOB")){
            logger.info("监听到用户事件 {} \t 流程实例id={}", type, event.getProcessInstanceId());
        }



    }

    @Override
    public boolean isFailOnException() {
        return false;
    }
}

​​​​​​​4.3 创建配置文件

创建对应的配置文件activiti-job.cfg.xml




    
         
          
        
         
        

        
            
                
            
        

    
    
        
    

    
        
        
        
        
        
            
        
    

    
           
           
          
          
          
          
          
    

    
    



 ​​​​​​​4.4 创建测试类

创建一个测视类,主要是打印定时job启动后的任务执行信息,任务执行信息是通过监听器来传递的。

import org.activiti.engine.event.EventLogEntry;
import org.activiti.engine.runtime.Job;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/07
 */
public class ConfigJobTest {

    private static final Logger logger = LoggerFactory.getLogger(ConfigJobTest.class);

    //这里已经包含了流程引擎的创建
    @Rule
    public ActivitiRule activitiRule = new ActivitiRule("activiti_job.cfg.xml");

    @Test
    @Deployment(resources = {"./my-process-job.bpmn20.xml"})
    public void Test1() throws InterruptedException {
        logger.info("start");
        List jobs = activitiRule.getManagementService().createTimerJobQuery().listPage(0, 100);

        for (Job  job:jobs){
            logger.info("定时任务={}, 默认重试次数={}", job, job.getRetries());
        }
        logger.info("jobs.size={}", jobs.size());
        Thread.sleep(1000*100);
        logger.info("end");

    }

}

​​​​​​​4.5 执行结果

在监听器中,我们代码指定了如果事件的类似为TIMER或者JOB的需要进行处理(打印)

Activiti6.0学习实践(5)-activiti流程引擎配置二_第18张图片

 

​​​​​​​5、与Spring集成

集成spring需要添加pom依赖activi-spring,基于Spring的默认配置是activiti-context.xml,核心服务需要注入Spring容器。如果需要单元测试,还需要在pom中添加spring-test,辅助测试Rule:ActivitiRule。下面通过一个demo来演示如何进行spring集成。思路是:先集成spring,然后通过自定义个bean,注入到流程的某个环节中。

​​​​​​​5.1 创建一下配置文件

创建一个配置文件activiti-context.xml,内容如下:





    
           
           
          
          
          
          
          
    
    
        
    

    
    
         
        
        
    

    
    
        
    

    
    
    
    
    
    

    
        
    
   

 ​​​​​​​5.2 创建测试类

创建一个测试类可以进行spring集成测试

import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/07
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:activiti_context.xml"})
public class ConfigSpringTest {

    private static final Logger logger = LoggerFactory.getLogger(ConfigSpringTest.class);

    //这里自动装配配置文件中的activitirule
    @Rule
    @Autowired
    public ActivitiRule activitiRule;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Test
    @Deployment(resources = {"./my-process.bpmn20.xml"})
    public void test() {

        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
        ;
        assertNotNull(processInstance);

        List list = taskService.createTaskQuery().list();
        for (Task task : list
        ) {
            taskService.complete(task.getId());
        }


    }

}

 ​​​​​​​5.3 执行日志

下图是执行日志的情况:

Activiti6.0学习实践(5)-activiti流程引擎配置二_第19张图片

注意一下,spring需要junit的版本在4.12以上,否则会报告如下错误。

Activiti6.0学习实践(5)-activiti流程引擎配置二_第20张图片

 ​​​​​​​5.4 设计自定义bean

下面设计一个自定义的bean,并注入到流程执行过程中。在流程配置文件中添加一个节点,并且这个节点执行这个bean的sayHello方法。创建一个类HelloBean

package com.study.activiti.delegate;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Describe:
 *
 * @author cwqsolo
 * @date 2020/01/29
 */
public class HelloBean {
    private static final Logger logger = LoggerFactory.getLogger(HelloBean.class);

    public void  sayHello(){
        logger.info("Hello world");
    }
}

在配置文件activiti_context.xml里配置bean的地方,加上这个bean的配置

Activiti6.0学习实践(5)-activiti流程引擎配置二_第21张图片

 ​​​​​​​5.5 创建一个新的流程定义

下面创建一个新的流程定义文件,在某个环节中配置上我们的自定义类

Activiti6.0学习实践(5)-activiti流程引擎配置二_第22张图片

 ​​​​​​​5.6 流程结合自定义bean执行日志

执行我们的测试类,在打印的信息中可以看到下面内容:

Activiti6.0学习实践(5)-activiti流程引擎配置二_第23张图片

你可能感兴趣的:(工作流,流程引擎,activiti)