activiti之spring管理监听器的方法

以下博客为转载,原文博客:http://blog.csdn.net/v_will/article/details/78001453

这篇文章主要记录流程监听器的部分用法,整个环境实在集成在spring下,ssm环境:
三个监听器:

A:普通javaBean:

    package com.abc.activiti.listenner;    

    import org.activiti.engine.delegate.DelegateExecution;  

    public class JavaExpressionActivitiListenner {  
        public void expression(DelegateExecution execution) throws Exception {  
            System.out.println("executionId:" + execution.getId() + " ActivitiListenner" + this.toString());  
        }  

B:实现ExecutionListener接口:

 package com.abc.activiti.listenner;  


    import org.activiti.engine.delegate.DelegateExecution;  
    import org.activiti.engine.delegate.DelegateTask;  
    import org.activiti.engine.delegate.ExecutionListener;  
    import org.activiti.engine.delegate.TaskListener;  


    public class ActivitiListenner implements TaskListener, ExecutionListener {  


        /** 
         *  
         */  
        private static final long serialVersionUID = -3759054058055401826L;  


        @Override  
        public void notify(DelegateExecution execution) throws Exception {  
            System.out.println("xml流程:" + execution.getId() + " ActivitiListenner" + this.toString());  
        }  


        @Override  
        public void notify(DelegateTask delegateTask) {  
            System.out.println("xml任务:" + delegateTask.getId() + " ActivitiListenner" + this.toString());  
        }  


    }

C:实现JavaDelegate接口

    package com.abc.activiti.listenner;  


    import org.activiti.engine.delegate.DelegateExecution;  
    import org.activiti.engine.delegate.JavaDelegate;  


    public class JavaDelegateActivitiListenner implements JavaDelegate {  


    @Override  
    public void execute(DelegateExecution execution) throws Exception {  
    System.out.println("executionId:" + execution.getId() + " ActivitiListenner" + this.toString());  



    }

第一种尝试:javaClass配置实现监听
流程设计:

流程非常短:启动-办理-结束,并配置了三个监听器

监听器配置:

 <span style="font-size:18px;"><span style="white-space:pre">    </span><process id="abc" name="流程监听注入" isExecutable="true">  
    <span style="white-space:pre">      </span><extensionElements>  
    <span style="white-space:pre">          </span><activiti:executionListener event="start"  
    <span style="white-space:pre">              </span>class="com.abc.activiti.listenner.xxxListenner"></activiti:executionListener>  
    <span style="white-space:pre">          </span><activiti:executionListener event="end"  
    <span style="white-space:pre">              </span>class="com.abc.activiti.listenner.xxxListenner"></activiti:executionListener>  
    <span style="white-space:pre">      </span></extensionElements>  
    <span style="white-space:pre">      </span><startEvent id="startevent1" name="Start"></startEvent>  
    <span style="white-space:pre">      </span><userTask id="usertask1" name="User Task"></userTask>  
    <span style="white-space:pre">      </span><sequenceFlow id="flow1" sourceRef="startevent1"  
    <span style="white-space:pre">          </span>targetRef="usertask1"></sequenceFlow>  
    <span style="white-space:pre">      </span><endEvent id="endevent1" name="End"></endEvent>  
    <span style="white-space:pre">      </span><sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1">  
    <span style="white-space:pre">          </span><extensionElements>  
    <span style="white-space:pre">              </span><activiti:executionListener event="take"  
    <span style="white-space:pre">                  </span>class="com.abc.activiti.listenner.xxxListenner"></activiti:executionListener>  
    <span style="white-space:pre">          </span></extensionElements>  
    <span style="white-space:pre">      </span></sequenceFlow>  
    <span style="white-space:pre">  </span></process></span>  

A类监听测试:

    <span style="font-size:18px;">2017-09-16 10:36:25.816 [http-nio-8080-exec-3] ERROR c.a.a.controller.ActivitiController.exception - 处理请求http://localhost:8080/abc-master/activiti/start?null 时出错。  
    完整异常栈堆信息  
    org.activiti.engine.ActivitiIllegalArgumentException: com.abc.activiti.listenner.JavaExpressionActivitiListenner doesn't implement interface org.activiti.engine.delegate.ExecutionListener nor interface org.activiti.engine.delegate.JavaDelegate</span>

启动流程时报错,说明通过javaClass配置activiti的流程监听器必须实现org.activiti.engine.delegate.ExecutionListener或者org.activiti.engine.delegate.JavaDelegate接口
B类监听测试:
流程启动-办理-结束,三个监听器的方法分别被执行:执行结果如下:

    <span style="font-size:18px;">xml流程:7f7aa2be-9a89-11e7-9d02-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@39ca6dcd  
    xml流程:7f7aa2be-9a89-11e7-9d02-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@306a75c6  
    xml流程:7f7aa2be-9a89-11e7-9d02-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@342664da</span>  

测试表明,通过加载java class的方式去加载实现了ExecutionListener接口的bean,可以顺利实现流程监听,但是每次获取的监听器都是一个新对象;
C类监听测试:
执行结果如下:

 <span style="font-size:18px;">executionId:eebefb34-9a89-11e7-b1f2-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@26d8afc4  
    executionId:eebefb34-9a89-11e7-b1f2-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@38835b92  
    executionId:eebefb34-9a89-11e7-b1f2-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@21dcaa6e</span>  

不出所料,其结果与B类监听一致;
进一步测试:spring容器注入bean:
可以设想一下,javaClass加载监听器的时,每次都是activitiEngine通过反射产生新的对象,因此此种方式下通过spring管理去注入可能会失败:
对实现了JavaDelegate的监听器进行改造:

 <span style="font-size:18px;">package com.abc.activiti.listenner;  

    import org.activiti.engine.delegate.DelegateExecution;  
    import org.activiti.engine.delegate.JavaDelegate;  
    import org.springframework.beans.factory.annotation.Autowired;  
    import org.springframework.stereotype.Service;  

    import com.abc.activiti.service.ActivitiService;  

    @Service  
    public class JavaDelegateActivitiListenner implements JavaDelegate {  

        @Autowired  
        private ActivitiService activitiService;  

        @Override  
        public void execute(DelegateExecution execution) throws Exception {  
            System.out.println("executionId:" + execution.getId() + " ActivitiListenner" + this.toString()  
                    + "  spring容器注入bean:" + activitiService.toString());  
        }  

    }</span>  

测试结果:
妥妥的空指针,注入失败:

    <span style="font-size:18px;">2017-09-16 10:57:01.760 [http-nio-8080-exec-3] ERROR c.a.a.controller.ActivitiController.exception - 处理请求http://localhost:8080/abc-master/activiti/start?null 时出错。  
    完整异常栈堆信息  
    java.lang.NullPointerException: null  
        at com.abc.activiti.listenner.JavaDelegateActivitiListenner.execute(JavaDelegateActivitiListenner.java:19) ~[JavaDelegateActivitiListenner.class:na]  
        at org.activiti.engine.impl.delegate.JavaDelegateInvocation.invoke(JavaDelegateInvocation.java:34) ~[activiti-engine-5.20.0.jar:na]</span>  

对实现了ExecutionListener的监听器进行改造:

 <span style="font-size:18px;">package com.abc.activiti.listenner;  


    import org.activiti.engine.delegate.DelegateExecution;  
    import org.activiti.engine.delegate.DelegateTask;  
    import org.activiti.engine.delegate.ExecutionListener;  
    import org.activiti.engine.delegate.TaskListener;  
    import org.springframework.beans.factory.annotation.Autowired;  
    import org.springframework.stereotype.Service;  


    import com.abc.activiti.service.ActivitiService;  


    @Service  
    public class ActivitiListenner implements TaskListener, ExecutionListener {  


    <span style="white-space:pre">  </span>/** 
    <span style="white-space:pre">  </span> *  
    <span style="white-space:pre">  </span> */  
    <span style="white-space:pre">  </span>private static final long serialVersionUID = -3759054058055401826L;  


    <span style="white-space:pre">  </span>@Autowired  
    <span style="white-space:pre">  </span>private ActivitiService activitiService;  


    <span style="white-space:pre">  </span>@Override  
    <span style="white-space:pre">  </span>public void notify(DelegateExecution execution) throws Exception {  
    <span style="white-space:pre">      </span>System.out.println("xml流程:" + execution.getId() + " ActivitiListenner" + this.toString());  
    <span style="white-space:pre">      </span>System.out.println("activitiService: " + activitiService.toString());  
    <span style="white-space:pre">  </span>}  


    <span style="white-space:pre">  </span>@Override  
    <span style="white-space:pre">  </span>public void notify(DelegateTask delegateTask) {  
    <span style="white-space:pre">      </span>System.out.println("xml任务:" + delegateTask.getId() + " ActivitiListenner" + this.toString());  
    <span style="white-space:pre">  </span>}  


    }  
    </span>  

测试结果:

    <span style="font-size:18px;">xml流程:03ec2a11-9a8b-11e7-903c-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@5de11ac2  
    2017-09-16 10:59:11.541 [http-nio-8080-exec-3] ERROR c.a.a.controller.ActivitiController.exception - 处理请求http://localhost:8080/abc-master/activiti/start?null 时出错。  
    完整异常栈堆信息  
    java.lang.NullPointerException: null  
    <span style="white-space:pre">  </span>at com.abc.activiti.listenner.ActivitiListenner.notify(ActivitiListenner.java:26) ~[ActivitiListenner.class:na]  
    <span style="white-space:pre">  </span>at org.activiti.engine.impl.delegate.ExecutionListenerInvocation.invoke(ExecutionListenerInvocation.java:34) ~[activiti-engine-5.20.0.jar:na]</span> 

以上两组结果表明,spring只是将其纳入管理,但并成功注入到activitiEngine中。
第二种尝试:expression配置实现监听
监听器配置:

 <span style="font-size:18px;"><process id="abc" name="流程监听注入" isExecutable="true">  
            <extensionElements>  
                <activiti:executionListener event="start"  
                    expression="${javaExpressionActivitiListenner.expression(execution)}"></activiti:executionListener>  
                <activiti:executionListener event="end"  
                    expression="${javaExpressionActivitiListenner.expression(execution)}"></activiti:executionListener>  
            </extensionElements>  
            <startEvent id="startevent1" name="Start"></startEvent>  
            <userTask id="usertask1" name="User Task"></userTask>  
            <sequenceFlow id="flow1" sourceRef="startevent1"  
                targetRef="usertask1"></sequenceFlow>  
            <endEvent id="endevent1" name="End"></endEvent>  
            <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1">  
                <extensionElements>  
                    <activiti:executionListener event="take"  
                        expression="${javaExpressionActivitiListenner.expression(execution)}"></activiti:executionListener>  
                </extensionElements>  
            </sequenceFlow>  
        </process></span>

A类监听测试:
需要注意的是,此时通过expression表达式注入时,是的

    <span style="font-size:18px;">2017-09-16 11:27:29.420 [http-nio-8080-exec-3] ERROR c.a.a.controller.ActivitiController.exception - 处理请求http://localhost:8080/abc-master/activiti/start?null 时出错。  
    完整异常栈堆信息  
    org.activiti.engine.ActivitiException: Unknown property used in expression: ${javaExpressionActivitiListenner.expression(execution)}  
        at org.activiti.engine.impl.el.JuelExpression.getValue(JuelExpression.java:53) ~[activiti-engine-5.20.0.jar:na]  
    ......  
    Caused by: org.activiti.engine.impl.javax.el.PropertyNotFoundException: Cannot resolve identifier 'javaExpressionActivitiListenner'  
        at org.activiti.engine.impl.juel.AstIdentifier.eval(AstIdentifier.java:83) ~[activiti-engine-5.20.0.jar:5.20.0]</span> 

监听器改造:

  <span style="font-size:18px;">package com.abc.activiti.listenner;  

    import org.activiti.engine.delegate.DelegateExecution;  
    import org.springframework.stereotype.Component;  

    @Component  
    public class JavaExpressionActivitiListenner {  

        public void expression(DelegateExecution execution) throws Exception {  
            System.out.println("executionId:" + execution.getId() + " ActivitiListenner" + this.toString());  
        }  
    }  
    </span>  

测试结果如下:

  <span style="font-size:18px;">executionId:ddd3f07e-9a8d-11e7-9fc5-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaExpressionActivitiListenner@420a38c6  
    executionId:ddd3f07e-9a8d-11e7-9fc5-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaExpressionActivitiListenner@420a38c6  
    executionId:ddd3f07e-9a8d-11e7-9fc5-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaExpressionActivitiListenner@420a38c6</span>  

B类监听测试:

测试结果:

    <span style="font-size:18px;">xml流程:2175ef09-9a8e-11e7-9af4-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@2f68610c  
    xml流程:2175ef09-9a8e-11e7-9af4-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@2f68610c  
    xml流程:2175ef09-9a8e-11e7-9af4-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@2f68610c</span>  

C类监听测试:

测试结果:

  <span style="font-size:18px;">executionId:719dc30a-9a8d-11e7-9ac9-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@7374d21e  
    executionId:719dc30a-9a8d-11e7-9ac9-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@7374d21e  
    executionId:719dc30a-9a8d-11e7-9ac9-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@7374d21e</span>  

进一步测试:spring注入bean:
测试结果:

 <span style="font-size:18px;">xml流程:2b882f40-9a91-11e7-9325-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@42e9857e  
    activitiService: com.abc.activiti.service.ActivitiService@2f9b021f  
    xml流程:2b882f40-9a91-11e7-9325-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@42e9857e  
    activitiService: com.abc.activiti.service.ActivitiService@2f9b021f  
    xml流程:2b882f40-9a91-11e7-9325-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@42e9857e  
    activitiService: com.abc.activiti.service.ActivitiService@2f9b021f</span>

此处仅提供A类监听测试结果,其余测试结果均一致,以上测试结果表明,使用expression表达式江容器中的bean作为监听器注入到activitiEngine中是一种非常灵活强大的方式。
第三种尝试:delegate expression配置实现监听
监听器配置:

    <span style="font-size:18px;">  <process id="abc" name="流程监听注入" isExecutable="true">  
            <extensionElements>  
                <activiti:executionListener event="start"  
                    delegateExpression="${activitiListenner}"></activiti:executionListener>  
                <activiti:executionListener event="end"  
                    delegateExpression="${activitiListenner}"></activiti:executionListener>  
            </extensionElements>  
            <startEvent id="startevent1" name="Start"></startEvent>  
            <userTask id="usertask1" name="User Task"></userTask>  
            <sequenceFlow id="flow1" sourceRef="startevent1"  
                targetRef="usertask1"></sequenceFlow>  
            <endEvent id="endevent1" name="End"></endEvent>  
            <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="endevent1">  
                <extensionElements>  
                    <activiti:executionListener event="take"  
                        delegateExpression="${activitiListenner}"></activiti:executionListener>  
                </extensionElements>  
            </sequenceFlow>  
        </process></span>  

A类监听测试:

 <span style="font-size:18px;">2017-09-16 12:21:54.134 [http-nio-8080-exec-3] ERROR c.a.a.controller.ActivitiController.exception - 处理请求http://localhost:8080/abc-master/activiti/start?null 时出错。  
    完整异常栈堆信息  
    org.activiti.engine.ActivitiIllegalArgumentException: Delegate expression ${javaExpressionActivitiListenner} did not resolve to an implementation of interface org.activiti.engine.delegate.ExecutionListener nor interface org.activiti.engine.delegate.JavaDelegate  
        at org.activiti.engine.impl.bpmn.listener.DelegateExpressionExecutionListener.notify(DelegateExpressionExecutionListener.java:57) ~[activiti-engine-5.20.0.jar:5.20.0]  
        at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:42) ~[activiti-engine-5.20.0.jar:na]</span>  

B类监听测试:

    <span style="font-size:18px;">xml流程:fcc6c8ba-9a95-11e7-826d-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@71425d05  
    activitiService: com.abc.activiti.service.ActivitiService@72a765d5  
    xml流程:fcc6c8ba-9a95-11e7-826d-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@71425d05  
    activitiService: com.abc.activiti.service.ActivitiService@72a765d5  
    xml流程:fcc6c8ba-9a95-11e7-826d-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.ActivitiListenner@71425d05  
    activitiService: com.abc.activiti.service.ActivitiService@72a765d5</span>  

C类监听测试:

 <span style="font-size:18px;">executionId:c96567e2-9a95-11e7-b7e3-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@6f660921  spring容器注入bean:com.abc.activiti.service.ActivitiService@1dc6b66a  
    executionId:c96567e2-9a95-11e7-b7e3-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@6f660921  spring容器注入bean:com.abc.activiti.service.ActivitiService@1dc6b66a  
    executionId:c96567e2-9a95-11e7-b7e3-b4b6761cb4ac ActivitiListennercom.abc.activiti.listenner.JavaDelegateActivitiListenner@6f660921  spring容器注入bean:com.abc.activiti.service.ActivitiService@1dc6b66a  
    </span> 

以上测试结果表明:
通过delegate expression配置容器中的监听器时,仍然需要实现ExecutionListener或者JavaDelegate接口
总结:
1
通过javaClass加载指定类,这种硬编码的形式管理监听器,是将class字节码文件交由activitiEngine处理,每次需要的时候则由engine通过反射构建实例对象,spring无法管理;
2
通过delegate expression配置容器中的bean作为监听器, beanorg.activiti.engine.delegate.ExecutionListenerorg.activiti.engine.delegate.JavaDelegatebeanspring3expressionbean {类名.方法名(参数名)};这是最为灵活也最为强大的方法,可以使用任意的bean,也可以自定义将要执行的方法,与spring容器无缝对接,与业务逻辑完美契合。

猜你喜欢

转载自blog.csdn.net/Dynamic_W/article/details/78338164