当前位置: 首页 > 工具软件 > jBPM > 使用案例 >

JBPM--十

卫鸿朗
2023-12-01

进阶篇

 

 一、该版本引入"子流程"<process-state>和<sub-process>节点
 (**使用这一套的时候应该特别注意,详细看一下这个项目的流程定义文件和下边的注释!!)
 
 需求:比如当我们提交给人力资源部审批的时候,人力资源部又另有一个小流程,
   就是所有提交人力资源部的审批文件,都要先经过一个小助理审批,然后决定是否交由人力资源部经理审批
   所以该人力资源部内部的这个流程就是一个子流程。
   
 **注意:当从process-state节点进入子流程的时候,他会忽略掉子流程中的start-state开始节点,
     从源码可以发现,当进入子流程之后,会直接调用subProcessInstance.signal()方法,
     这样就导致流程直接流过了start-state开始节点,所以不要在子流程的start-state开始节点分配任务。
     
 实现时注意:对于我们的业务来说可以说成是子流程,但是在程序中子流程将作为一个新的流程出现,
   也就是子流程产生的流程对象和不流程的流程对象没有太大的关系,因为我们在父流程对象中绑定设定了很多参数变量值,
   也包括请假单对象的id,因为子流程在整个处理过程中和父流程处理的方式基本一样,但是子流程作为一个新的流程对象,
   该流程对象中并没有父流程对象中已经设置存在的那些变量参数值,如果想让子流程中也具有这些变量,那么必须做一个映射,
   只需做一个配置,也就是将父流程对象中指定的变量及其值复制到子流程对象中来,
   这样子流程就可以用这些设定在父流程对象中的变量及其值。
   
 具体实现:
   <process-state name="superStateName">
    <sub-process name="子流程定义文件的名称"></sub-process>
    <variable name="父流程中变量的名字" access="read,write" mapped-name="映射到子流程中的变量名称"></variable>
    <transition name="transitionName" to="子流程完全结束后会流向这里指定的节点"></transition>
   </process-state>
   说明:access="read,write"表示在子流程中可读也可写,所谓的可写就是在子流程对象中如果改变了变量的值,
    那么父流程对象中的相应的变量的值也会跟着改变,如果没有指定为可读write,
    那么改变子流程对象中的变量值父流程对象中的值是不会改变的,当子流程结束后那么子流程对象中的变量就会销毁。
   
   
   
 **注意:使用的时候各个节点的状态可能会有点儿出路,用的时候再具体问题具体分析!!
     
 实际应用是应小心的地方:
 
     1.因为测试结果是进入子流程的第一个节点后,状态中不显示子流程的节点名称,
    而是显示<process-state name="superStateName">中的name的值,
     2.这里注意一下,还有就是我们对请假单当遇到结束节点是让请假单的状态改为了“完成审批”,
    由于子流程中的结束节点也符合这个条件,所以当子流程结束后请假单也会显示审批结束,
    而其实子流程结束后会返回父流程中中接续执行,这里应该注意一下。
   
   
 二、对于<state>和<node>节点的说明:
   <state>节点就是一个节点,当流程流转到<state>节点的时候,流程被挂起,
     此时要我们手动调用signal方法,流程才会继续向下流转,
     该节点中不能加入<task>任务,即便是加入了也不会执行。
     所以该节点的用处就是可以在节点中加入<action>事件,
     事件中必须要调用signal方法,这样才能是流程继续向下一个节点流转,
     如果不调用,那么流程将会永远停留在该节点。
     
     作用:该节点的目的就是可以在<action>事件方法中除了调用signal方法外可以加入一些自己需求所用到的其他代码(例如发邮件等操作)。
     
   <node>节点,流程流转到该节点的时候不会停留,而是直接进入该节点然后紧接着离开该节点,流向下一个节点。
   
   
 三、对于<mail-node>的说明:是用来发邮件的节点,就是说当流程流转到这里的时候,
    JBPM会根据指定的配置信息进行发邮件,发完邮件后流程继续向下进行,对于JBPM对这个节点的开发有点儿多余,
    因为发邮件的工作完全可以交给<action>来完成。
    
    使用方式:只能有一个<transition>元素
      <mail-node name="nodeName" to="#{可用变量来指定接收邮件的地址}" subject="邮件主题" text="邮件内容">
       <transition name="transitionName" to="flowToName"></transition>
      </mail-node>
      
    新版本提供的另一种方式:这种方式,首先知道<mail>不是节点,该元素可以放到<task>内部,作为<task>的一部分
     <mail actors="#{收件人地址的变量}">
      <subject>邮件主题</subject>
      <text>邮件内容</text>
     </mail>
     
   另外在jbpm.cfg.xml配置文件中要加入对邮件服务的支持:
     <string name="resource.mail.properties" value="jbpm.mail.properties">
     
     其中properties的配置方式:
      mail.host=smtp.126.com
      mail.smtp.auth=true
      mail.from.address=yourmail@126.com
      mail.smtp.user=yourmail@126.com
      mail.smtp.password=yourpassword
     
     需要注意的是,有些服务器需要发邮件人和待认证用户一致才可以发邮件
     
   注意:该发邮件的节点和元素只做了解,因为实际应用中不用这套机制,用<action>来代替,我们一样能实现一样的功能!!
   
   
 四、对于<task>元素中的<controller>元素的说明,该元素可以为包含它的任务定义任务变量,
  也就是生命周期为任务的生命周期,<controller>里面可以通过<variable>来制定变量,
  这个指定变量的方法也是将流程变量映射到任务变量
  这和<process-state>节点中使用 <sub-process>时,为子流程映射变量差不多不过有点儿不同,
  不同就是,在<variable>中可以指定一个流程变量中没有的变量,
  这种情况下会同时也在流程变量中加入一个该变量指定的变量,至于access属性指定的值,和之前子流程中的意思相同。
  "具体可以查看文档"这个用到的不是很多
 
 五、JBPM的定时器timer的说明:(了解)
 
  1.在流程定义的节点中加入声明:这里以<state>节点为例
   <state name="nodeName">
    <timer name="timerName" duedate="0 seconds" repeat="10 seconds">
     <script>System.out.println("Here");</script>
    </timer>
   </state>
   **说明:该配置将在部署流程定义文件的时候存入JBPM提供的数据库表Timer
   
  2.运行时当然要有一个线程来不是的监控JBPM的时间服务,来衡量什么时候启动定时器timer。
    JBPM的机制就是由Timer Runner来扫描Timer表,然后执行符合调度条件的Timer逻辑
    所以还要配置一个servlet到web.xml配置文件:该servlet将会产生一个Timer Runner进行监控
     <servlet>
      <servlet-name>JobExecutorServlet</servlet-name>
      <servlet-class>org.jbpm.job.executor.JobExecutorServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>
      ......
     </servlet-mapping>
     
 六、添加自定义的节点类型:即我们可以按照我们的实际需求定义符合我们自己的实际需求的节点类型,
     因为JBPM给我们提供的那些节点类型肯定不会适应所有的实际情况。(了解)
     
     1.在org/jbpm/graph/node/node.types.xml中添加节点信息
      <node-type element="archive-node" class="org.jbpm.graph.node.ArchiveNode"></node-type>
      
     2.编写自己的实现类(继承Node类):主要覆盖read()方法和execute()方法!

 

 

 

 

 类似资料: