activiti監聽器


疑問:當我們流程流轉到某一節點、某一連線或者流程開始和結束的時候我們怎么添加一些業務處理呢?

這就是我們今天討論的主題了。

activiti的監聽應用場景:在某一流程開始或者結束的時候,我們可以加入部分的業務處理,例如:在流程結束后,我們發郵件或者推送短信給我們的申請人,告訴他審批完成。又或者,當有審批人不同意該次請求的時候,我們也需要通知申請人,讓其修改該申請。又或者該流程流轉到某一節點,也就是需要他審批的時候,需要通知負責人,這時候也可以使用該監聽。也可以用在指定下一個節點的處理人等等。

activiti的監聽器分為:全局監聽、連線監聽、節點監聽。

本次演示使用的流程圖如下:

  

  全局監聽:

    主要用於監聽流程的開始和結束。

    bpmn xml文件如下:

     如何去實現呢?我們可以在bpmn的xml文件的 <process id="BookProcess" name="BookProcess" isExecutable="true">的下面添加上我們的監聽配置:

<extensionElements>
      <activiti:executionListener event="start" class="com.listener.MyExecutionListener"></activiti:executionListener>
      <activiti:executionListener event="end" class="com.listener.MyExecutionListener"></activiti:executionListener>
    </extensionElements>

  其中MyExecutionListener是我們自己定義的監聽器類,該類需要實現ExecutionListener接口:

public class MyExecutionListener implements ExecutionListener {

    public void notify(DelegateExecution delegateExecution) throws Exception {

        String eventName = delegateExecution.getEventName();
        
        if ("start".equals(eventName)) {
            System.out.println("start=========");
        }else if ("end".equals(eventName)) {
            System.out.println("end=========");
        } else if ("take".equals(eventName)) {//連線監聽
            System.out.println("take=========");
        }
    }
}

  這樣我們就可以在start或者end的下面添加一些業務處理。

  在DelegateExecution對象中,可獲取到的參數有如下:

public interface DelegateExecution extends VariableScope {
    String getId();

    String getProcessInstanceId();

    String getEventName();

    /** @deprecated */
    String getBusinessKey();

    String getProcessBusinessKey();

    String getProcessDefinitionId();

    String getParentId();

    String getCurrentActivityId();

    String getCurrentActivityName();

    String getTenantId();

    EngineServices getEngineServices();
}

  通過上述的參數可獲取到我們需要的參數,例如getProcessBusinessKey()獲取到業務id,通過業務id可以修改我們業務單的狀態等等。

  

  連線接聽:

    當我們的流程經過某一連線的時候,需要實現一些業務,這就需要連線監聽。

    連線監聽的實現和全局監聽類似,都需要去實現實現ExecutionListener接口,該接口可獲取到所需的參數。

    我們只需要在bpmn 的xml的連線下添加監聽配置;

 <sequenceFlow id="flow6" name="不同意" sourceRef="usertask2" targetRef="usertask1">
      <extensionElements>
        <activiti:executionListener event="take" class="com.listener.MyExecutionListener"></activiti:executionListener>
      </extensionElements>
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='不同意'}]]></conditionExpression>
    </sequenceFlow>

  extensionElements中就是添加我們的監聽類,每當流程經過該連線的時候,就會進入MyExecutionListener類,執行else if ("take".equals(eventName))下的代碼。這樣我們就可以在該方法下面添加我們需要的業務處理。

  節點監聽:

    當流程轉到某一節點的時候,需要觸發我們自定義的業務,這一節點監聽在流程中是經常使用的。

    首先,我們需要自定義我們的監聽類,自定義監聽類需要實現TaskListener接口;

    自定義類如下:

public class MyTaskListener implements TaskListener {
    
    public void notify(DelegateTask delegateTask) {
        String eventName = delegateTask.getEventName();
        if ("create".endsWith(eventName)) {
            System.out.println("create=========");
        }else if ("assignment".endsWith(eventName)) {
            System.out.println("assignment========"+delegateTask.getAssignee());

        }else if ("complete".endsWith(eventName)) {
            System.out.println("complete===========");
        }else if ("delete".endsWith(eventName)) {
            System.out.println("delete=============");
        }
    }
}

  DelegateTask對象中,我們可以獲取到參數有如下:

  

public interface DelegateTask extends VariableScope {
    String getId();

    String getName();

    void setName(String var1);

    String getDescription();

    void setDescription(String var1);

    int getPriority();

    void setPriority(int var1);

    String getProcessInstanceId();

    String getExecutionId();

    String getProcessDefinitionId();

    Date getCreateTime();

    String getTaskDefinitionKey();

    boolean isSuspended();

    String getTenantId();

    String getFormKey();

    void setFormKey(String var1);

    DelegateExecution getExecution();

    String getEventName();

    DelegationState getDelegationState();

    void addCandidateUser(String var1);

    void addCandidateUsers(Collection<String> var1);

    void addCandidateGroup(String var1);

    void addCandidateGroups(Collection<String> var1);

    String getOwner();

    void setOwner(String var1);

    String getAssignee();

    void setAssignee(String var1);

    Date getDueDate();

    void setDueDate(Date var1);

    String getCategory();

    void setCategory(String var1);

    void addUserIdentityLink(String var1, String var2);

    void addGroupIdentityLink(String var1, String var2);

    void deleteCandidateUser(String var1);

    void deleteCandidateGroup(String var1);

    void deleteUserIdentityLink(String var1, String var2);

    void deleteGroupIdentityLink(String var1, String var2);

    Set<IdentityLink> getCandidates();
}

  通過該對象可以獲取處理人,或者指定下一個處理人等等。

  接着,我們需要在bpmn的xml文件中配置監聽類,在我們的任務節點中加入extensionElements配置,其中class是我們自定義的監聽類:

 <userTask id="usertask2" name="部門審批" activiti:assignee="${orguser}">
      <extensionElements>
        <activiti:taskListener event="all" class="com.listener.MyTaskListener"></activiti:taskListener>
      </extensionElements>
    </userTask>

  當流程轉到該節點的時候,就會觸發該類執行,這樣我們就可以加入我們的業務處理了。

 

除了我們直接在bpmn的xml文件中配置外,我們也可以通過如下方法添加全局、連線、節點的自定義監聽類:

  

 

以上就是全局、連線、以及節點監聽的描述與介紹,當然也需要執行驗證,執行驗證類如下:

  我們驗證類是結合spring的方式:

  驗證類:

public class activitiTest extends SpringBase {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Test
    public void deploymentProcessDefinition() {
        Deployment deployment = repositoryService.createDeployment()
                .name("Book")
                .addClasspathResource("BookProcess.bpmn")
                .deploy();
        System.out.println("deploymentId=" + deployment.getId());
        System.out.println("deploymentName=" + deployment.getName());
    }

    /**
     * 執行流程實例
     */
    @Test
    public void startProcessInstance() {
        String processInstanceKey = "BookProcess";
        Map<String,Object> values = new HashMap<String,Object>();

        values.put("inputUser","張三");
        values.put("orguser","李四");
        values.put("adminId","王五");
        String objId="Book"+"."+"123";
        values.put("objId",objId);
        ProcessInstance pi = runtimeService
                .startProcessInstanceByKey(processInstanceKey,objId,values);
        System.out.println("流程實例id:" + pi.getId());  //流程實例id  101
        System.out.println("流程定義id:" + pi.getProcessDefinitionId());   //流程定義ID helloworld:1:4
    }
    /**
     * 查找個人當前的要執行的任務
     */
    @Test
    public void findMyTaskInfo(){
        String assignee = "李四";//流程流轉的處理的人物
        List<Task> listTask = taskService
                .createTaskQuery()
                .taskAssignee(assignee)
                .list();
        if (listTask!= null && listTask.size() >0) {
            for (Task task : listTask) {
                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.getProcessDefinitionId());
                System.out.println("執行對象的ID:" + task.getExecutionId());
                System.out.println("任務的班里人:" + task.getAssignee());
                System.out.println("流程定義ID:" + task.getProcessInstanceId());
            }
        }
    }
    /**完成任務*/
    @Test
    public void completeMyPersoinTask() {
        String taskId = "60003";
        Map<String, Object> variables = new HashMap<String,Object>();
        variables.put("outcome","同意");
        taskService.complete(taskId,variables);
      /*  taskService.complete(taskId);*/
        System.out.println("完成任務,任務ID:" + taskId);
    }

}

  SpringBase類:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:/applicationContext.xml" })
public class SpringBase {
}

  applicationContext.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:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">

<!-- 引入properties文件  -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 掃描注解 -->

   <context:component-scan base-package="com"/>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="maxActive" value="300" />
        <property name="maxIdle" value="30" />
        <property name="minIdle" value="10" />
        <property name="initialSize" value="15" />
        <property name="maxWait" value="20000" />
    </bean>

    <!-- 事務管理 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 配置事務通知屬性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 定義事務傳播屬性 -->
        <tx:attributes>
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />
            <tx:method name="*" propagation="REQUIRED" read-only="true" />
        </tx:attributes>
    </tx:advice>
    
    <!-- 引擎  -->
    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
        <!-- 數據源 -->
        <property name="dataSource" ref="dataSource" />

        <!-- 配置事務,統一事務  -->
        <property name="transactionManager" ref="transactionManager" />

        <!--設置建表策略  -->
        <property name="databaseSchemaUpdate" value="true" />

    </bean>

    <!-- 創建引擎對象 -->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>

    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
    <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
    <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
    <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
    <bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
  
</beans>

 

  本人在這就不把執行結果展示出來了,大家可以自己運行測試一下。如有錯誤的地方請大家指正。

  

 

 

    

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM