《jbpm开发手册.docx》由会员分享,可在线阅读,更多相关《jbpm开发手册.docx(125页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第1章简介1.1.目标读者这个开发指南是为了给有经验的开发者看的, 这样就可以获得jBPM的完全的灵活性。在这个开发文档中提及的特性 可能当前不会被支持到。请自行使用。 1.2.概述第2章 孵化器 解释了最终会放到用户手册中的功能, 它们会成为支持的一部分。 要注意孵化器中的功能还没有确保稳定。 (比如这里可能主要的语法或实现在下一个版本中被改变)。 第3章 BPMN 2.0 介绍如何在jBPM中使用BPMN 2.0流程语言。 第5章 流程虚拟机 到 第9章 高级图形执行 解释了jBPM的核心,流程虚拟机(PVM),活动和事件监听器 是如何建立在它上面的。 第10章 配置 到 第18章 Sig
2、navio web建模器 解释了jBPM框架的高级用法。 1.3.源代码和WIKIjBPM的源代码可以在我们的SVN获得:https:/anonsvn.jboss.org/repos/jbpm/jbpm4/ 这里有一篇关于如何构建源代码的wiki:http:/www.jboss.org/community/docs/DOC-12867 jBPM的WIKI地址在:http:/www.jboss.org/community/docs/DOC-11184 1.4.Maven仓库你可以使用发布包中包含的jBPM和对应的依赖库。发布包中的jbpm.jar 包含了许多jBPM模块中的泪:jbpm-api,
3、 jbpm-log, jbpm-test-base, jbpm-pvm, jbpm-jpdl和jbpm-enterprise。 所以单独使用发布包中的jbpm.jar 不会在编译时区分API类和实现类。 如果你想只依赖jBPM的API,来构建一个自己的工程, 可以直接使用我们的仓库。它的地址在: 1.5.依赖库如果你想在自己的项目中安装或部署jBPM,现在也比以前方便了很多: 只需要把正确的jar放到系统的classpath下。 我们还没有清理maven pom文件中的依赖描述。所以我们还不能给出lib 目录下,你需要包含到应用中的,jar的最小集合。 (参考Jira issue JBPM-2
4、556 然后进行投票,如果你希望让我们知道这些问题对你优先级很高)。 依赖库的版本放在lib,是我们测试过的。 所以我们推荐你使用lib目录下的依赖版本。 为了在这方面帮助你,这里有一个jPDL当前所用的maven依赖的列表: INFO -INFO Building jBPM 4 - jPDLINFO task-segment: dependency:treeINFO -INFO dependency:treeINFO org.jbpm.jbpm4:jbpm-jpdl:jar:4.0INFO +- org.jbpm.jbpm4:jbpm-pvm:jar:4.0:compileINFO | +-
5、 org.jbpm.jbpm4:jbpm-api:jar:4.0:compileINFO | | - jboss:jboss-j2ee:jar:4.2.2.GA:compileINFO | +- org.jbpm.jbpm4:jbpm-log:jar:4.0:compileINFO | +- org.jbpm.jbpm4:jbpm-test-base:jar:4.0:compileINFO | | - org.hibernate:hibernate-core:jar:3.3.1.GA:compileINFO | | +- antlr:antlr:jar:2.7.6:compileINFO |
6、| - commons-collections:commons-collections:jar:3.1:compileINFO | +- org.apache.ant:ant:jar:1.7.0:compileINFO | | - org.apache.ant:ant-launcher:jar:1.7.0:compileINFO | +- log4j:log4j:jar:1.2.14:compileINFO | +- juel:juel:jar:2.1.0:compileINFO | +- juel:juel-impl:jar:2.1.0:compileINFO | +- juel:juel-
7、engine:jar:2.1.0:compileINFO | +- org.slf4j:slf4j-api:jar:1.5.2:compileINFO | +- org.slf4j:slf4j-jdk14:jar:1.5.2:compileINFO | +- org.jboss.identity.idm:idm-core:jar:1.0.0.Beta1:compileINFO | | +- org.jboss.identity.idm:idm-common:jar:1.0.0.Beta1:compileINFO | | +- org.jboss.identity.idm:idm-api:jar
8、:1.0.0.Beta1:compileINFO | | +- org.jboss.identity.idm:idm-spi:jar:1.0.0.Beta1:compileINFO | | - com.sun.xml.bind:jaxb-impl:jar:2.1.8:compileINFO | | - javax.xml.bind:jaxb-api:jar:2.1:compileINFO | | - javax.xml.stream:stax-api:jar:1.0-2:compileINFO | +- org.jboss.identity.idm:idm-hibernate:jar:1.0.
9、0.Beta1:compileINFO | | +- javassist:javassist:jar:3.4.GA:compileINFO | | +- org.hibernate:hibernate-cglib-repack:jar:2.1_3:compileINFO | | - org.slf4j:slf4j-log4j12:jar:1.5.2:compileINFO | +- org.hibernate:hibernate-entitymanager:jar:3.4.0.GA:compileINFO | | +- org.hibernate:ejb3-persistence:jar:1.
10、0.2.GA:compileINFO | | +- org.hibernate:hibernate-commons-annotations:jar:3.1.0.GA:compileINFO | | +- org.hibernate:hibernate-annotations:jar:3.4.0.GA:compileINFO | | +- dom4j:dom4j:jar:1.6.1:compileINFO | | | - xml-apis:xml-apis:jar:1.0.b2:compileINFO | | - javax.transaction:jta:jar:1.1:compileINFO
11、 | +- org.livetribe:livetribe-jsr223:jar:2.0.5:compileINFO | - javax.mail:mail:jar:1.4.1:compileINFO | - javax.activation:activation:jar:1.1:compileINFO +- junit:junit:jar:3.8.1:compileINFO - hsqldb:hsqldb:jar:1.8.0.7:testINFO -jboss的idm依赖在 org.jboss.identity.idm:*部分,可以忽略, 包含org.hibernate:hibernate-
12、entitymanager这个列表应该已经让你开始选择一个子集,而不是从 $jbpm.home/lib目录下包含所有依赖库。 第2章孵化器这一章介绍了一些更高级的jPDL的活动和功能, 这些功能还在开发中。意味着这些jPDL的功能和活动现在还没有被支持。 但是它们可以让你尝试使用一下。 我们不会为这些活动和功能提供已经稳定的保证。 所以要自己承担风险。 2.1.timer定时器 重要提示:定时器会被修改,在它们放到用户手册之前。 参考 https:/jira.jboss.org/jira/browse/JBPM-2329 一个定时器可以被指定在transition元素中 在等待活动比如stat
13、e, task,sub-process 和group中。 当这个定时器被触发,那个流向就会被执行。 一个定时器可以被指定在自定义事件中,在等待或东西 比如state, task,sub-process 和group中。 timer元素应该是on元素表示的事件的第一个元素。 在这里,事件根据定时器的持续时间被触发。 当进入这个活动时定时器被创建。 定时器可以触发当流程一直处于这个活动,直到duedate。 当流程离开活动,定时器就会被取消。 表2.1.timer属性:属性类型默认值是否必填描述duedate持续时间表达式必填指定什么时候定时器需要触发。 比如:20分钟或 3个工作日。 repea
14、t持续时间表达式optional当定时器触发,这个属性指定什么时候定时器需要再次触发。 比如:20分钟或 3个工作日。 2.1.1.持续时间表达式持续时间表达式包含下列语法:quantity business second | seconds | minute | minutes | hour | hours | day | days | week | weeks | month | months | year | years这里的quantity是一个正整数。 添加额外的business意味着 只有工作时间应该被计算在持续时间内。 如果没有指定business,持续时间会使用绝对时间间隔。
15、关于如何配置工作时间的解释在第2.1.2节 “工作日历”。 2.1.2.工作日历默认的配置会包含对 jbpm.business.calendar.xml文件的引用。 那包含了一个工作时间的配置,向下面的配置格式: 如果默认的工作日历实现能够满足你, 你可以直接在xml配置里像上面那样调整时间。 如果默认实现没有覆盖你的用例,你可以简单重写自己的实现 通过实现 org.jbpm.pvm.internal.cal.BusinessCalendar接口。 比如: public class CustomBusinessCalendar implements BusinessCalendar publi
16、c Date add(Date date, String duration) if (my next birthday.equals(duration) GregorianCalendar gregorianCalendar = new GregorianCalendar(); gregorianCalendar.set(Calendar.MONTH, Calendar.JULY); gregorianCalendar.set(Calendar.DAY_OF_MONTH, 21); return gregorianCalendar.getTime(); return null; 如果希望配置j
17、BPM引擎使用自定义工作日历, 只需要在你的jbpm.cfg.xml中添加如下配置: 看一下这个 org.jbpm.test.custombusinesscalendarimpl.CustomBusinessCalendarImplTest 可以获得更多信息。 2.1.3.定时器流向例子 org.jbpm.examples.timer.transition.TimerTransitionTest 展示如何把一个定时器放到流向上。图2.1.定时器流向示例流程 当这个流程的一个流程实例被启动, 它会到达guardedWait状态。 在那时候,一个定时器会被创建,在十分钟后触发。 Execution
18、 processInstance = executionService .startProcessInstanceByKey(TimerTransition);和下面的query,我们可以为定时器查询关联的流程实例。 我们知道这里应该有一个对应的这样的定时器。 Job job = managementService.createJobQuery() .timers() .processInstanceId(processInstance.getId() .uniqueResult(); 在一个单元测试中,我们不会使用JobExecutor来执行定时器。 相对的,我们在单元测试的线程中直接执行定
19、时器。 那样很简单在流程中模拟一个场景。 所以在下一步,我们假设定时器被处罚了。 我们通过编码执行定时器进行模拟: managementService.executeJob(job.getDbid();在那之后,流程实例会进入timeout流向 并移动到escalation状态。 processInstance = executionService.findExecutionById(processInstance.getId();assertEquals(escalation, processInstance.getActivityName();TimerTransitionTest的第二个
20、场景展示了定时器被取消, 这里执行singal go on,在定时器触发之前。 这种情况,流程会在 next step结束。 2.1.4.定时器事件示例TimerEventTest展示了如何把定时器放到自定义事件中。图2.2.定时器事件示例流程 这里,如果流程没有在开始以后10分钟内执行singal, 事件timeout就会被触发 事件监听器org.jbpm.examples.timer.event.Escalate 将被触发。 再一次,如果guardedWait活动在10分钟内被结束, 然后定时器就会被取消, Escalate事件监听器也不会执行。 2.1.5.定时器工作时间示例TimerB
21、usinessTimeTest展示工作定时器如何工作。图2.3.定时器工作时间示例流程 试想一个新的TimerBusinessTime流程实例在周二的上午11:30启动。 默认配置好的工作日历指定工作时间在9:00-12:00和12:30-17:00。 所以9个工作小时以后, 结果的真实持续时间是周三的下午13:00。 当我们不知道什么时候TimerBusinessTimeTest将执行时,我们只能在测试里验证 真实的计划定时器的持续时间最少是24小时以上。 2.1.6.定时器重复示例TimerRepeatTest展示了如何把定时器重复执行。 定时器里的repeat属性将导致定时器重新自动安排
22、 在它执行以后。 图2.4.定时器重复示例流程 当启动一个新流程,一个定时器被创建,持续时间是20分钟。 当定时器触发,在10秒之内一个新定时器会被创建。 当定时器触发,在10秒之内一个新定时器会被创建。 一直这样持续着。 每次定时器触发。新定时器就会被创建,直到 guardedWait状态活动被signal结束。 当guardedWait 状态活动结束, 定时器就会被取消。 2.2.group活动group会包括流程中的一系列活动。包含的组必须是被内嵌的。 一个组就对应着一个BPMN的子流程。 表2.2.group元素:元素数目描述any activity0.*包含的活动。 transiti
23、on0.*对于group活动的向外转移。 2.2.1.简单group这个实例场景演示了一个group的基本操作。 图2.5.简单group实例流程 下面的代码片段展示了一个测试环境, 当第一次到达collect feedback时,会拒绝一个文档。 然后它会到达update document, distribute document 然后返回collect feedback。 第二次,它会被接收。所有调用的活动都是等待state。 ProcessInstance processInstance = executionService .startProcessInstanceByKey(Grou
24、pSimple);String pid = processInstance.getId();assertEquals(distribute document, processInstance.getActivityName();processInstance = executionService.signalExecutionById(pid);assertEquals(collect feedback, processInstance.getActivityName();processInstance = executionService.signalExecutionById(pid, r
25、ejected);assertEquals(update document, processInstance.getActivityName();processInstance = executionService.signalExecutionById(pid);assertEquals(distribute document, processInstance.getActivityName();processInstance = executionService.signalExecutionById(pid);assertEquals(collect feedback, processI
26、nstance.getActivityName();processInstance = executionService.signalExecutionById(pid, approved);assertEquals(publish document, processInstance.getActivityName();2.2.2.group定时器图2.6.group定时器实例流程 下面的代码片段演示了一个测试场景,定时器会在evaluate document 这个group活动完成的时候触发。 ProcessInstance processInstance = executionServic
27、e .startProcessInstanceByKey(GroupTimer);Execution approveExecution = processInstance .findActiveExecutionIn(approve);assertNotNull(approveExecution);List jobs = managementService .createJobQuery() .processInstanceId(processInstance.getId() .list();assertEquals(1, jobs.size();Timer timer = (Timer) j
28、obs.get(0);managementService.executeJob(timer.getDbid();processInstance = executionService .findProcessInstanceById(processInstance.getId();assertNotNull(processInstance.findActiveExecutionIn(escalate) );2.2.3.group多入口这演示了一个group可以有多个唯一性的入口点。模拟一个多入口点, 一个group也可以有多个退出点。图2.7.group多入口实例流程 下面的场景将在有足够的时间
29、的时候执行: Map variables = new HashMap();variables.put(time, plenty);ProcessInstance pi = executionService .startProcessInstanceByKey(GroupMultipleEntries, variables);assertNotNull(pi.findActiveExecutionIn(distribute document);下面的场景将在没有足够的时间的时候执行: Map variables = new HashMap();variables.put(time, runnin
30、g out);ProcessInstance pi = executionService .startProcessInstanceByKey(GroupMultipleEntries, variables);assertNotNull(pi.findActiveExecutionIn(make planning);2.2.4.group同步这个场景演示了,一个group如何用来创建同步流程。 当一个流程到达一个group,每个没有进入转移的活动都会被启动。 所以第一个活动不一定是开始活动。 group会通过默认转移退出, 当所有包含的工作都已经完成的时候。 图2.8.group同步实例流程