首页

JBPM4.4知识点分类&相关示例代码笔记整理分享

标签:jbpm4.4     发布时间:2022-11-13   

一、知识点分类

1)JBPM4表详细说明,分类说明参节其他文章

JBPM4_DEPLOYMENT   流程定义表@b@JBPM4_DEPLOYPROP 流程定义属性表@b@JBPM4_EXECUTION  流程实例表@b@JBPM4_HIST_ACTINST 流程活动( 节点) 实例表@b@JBPM4_HIST_DETAIL  流程历史详细表@b@JBPM4_HIST_PROCINST 流程实例历史表@b@JBPM4_HIST_TASK  流程任务实例历史表@b@JBPM4_HIST_VAR  流程变量( 上下文) 历史表@b@JBPM4_ID_GROUP 组表@b@JBPM4_ID_MEMBERSHIP 用户角色表@b@JBPM4_ID_USER  用户表@b@JBPM4_JOB  定时表@b@JBPM4_LOB  存储表  存放流程定义的xml和png图片文件@b@JBPM4_PARTICIPATION 参与者表@b@JBPM4_SWIMLANE  泳道表@b@JBPM4_TASK 任务表@b@JBPM4_VARIABLE 上下文表

2)工作流的基本思路

2.1 、描述工作流@b@2.2 、发布和存储工作流@b@2.3 、装载和解析工作流@b@2.4 、顶层对象:流程、活动、转移@b@2.5 、流程定义和流程实例@b@2.6 、活动定义和活动实例@b@2.7 、令牌驱动,petri网@b@2.8 、转移:隐式、显示、fork(分支)、join、按条件等等@b@2.9 、活动:人工活动、自动活动等@b@2.10、人工活动会涉及:活动的处理页面、活动的数据@b@2.11、workList:活动的列表、接收、拒收、重分配、活动的响应等

3)jBPM有什么,简介jBPM的Service API

1:ProcessEngine:流程引擎。并不负责具体的业务,而是用于获取各种Service。@b@2:RepositoryService:流程资源服务的接口,如流程定义发布、查询、删除等。@b@{@b@    在流程仓库里包含部署管理、@b@}@b@3:ExecutioService:用于操作流程实例的服务,可以进行流程实例发布、查询、流程推进、设置流程变量等操作。@b@4:TaskService:用于操作人工任务的服务,可以进行任务创建、查询、获取、提交完成、保存、删除等操作。@b@5:HistoryService:用于操作流程历史的服务,提供对流程历史库(就是已经完成的流程实例)的操作。比如:历史流程实例,历史活动实例等。@b@6:IdentityService:用于操作用户、用户组以及成员关系的服务@b@7:ManagementService:流程管理控制服务的接口,只提供异步工作(Job)相关的执行和查询操作。

4)jPDL基础--1

jPDL(JBoss jBPM Process Definition Language)是构建于jBPM框架上的流程语言之一。在jPDL中提供了任务(tasks)、待@b@处理状态(wait states)、计时器(timers)、自动处理(automated@b@actions)…等术语,并通过图型化的流程定义,很直观地描述业务流程。@b@n 流程定义(ProcessDefinition)@b@就是对一个流程抽象的对象化定义。一套系统中,用户可以定义并保存多@b@个流程定义实体,如:报销流程定义、请假流程定义、人事录用流程定义等。@b@n 流程节点@b@是对流程中的过程环节/行为的抽象对象化定义。结点有两个主要职责:@b@一,实现某个指定行为,这在jBPM中就是执行一段制定的Java代码;二,传递、@b@维持流程的延续,直至达到最终结点。@b@流程实例(ProcessInstance)@b@流程实例是流程定义的运行时状态,它记录了一个流程运行的起始时间、@b@结束时间等状态信息。@b@n 任务实例(Task)@b@用来描述一个任务实例对象,可以分配给指定的操作者处理,当任务完成@b@后,将触发流程继续向下流转。任务实例的生命周期很简单,生成实例-->处理-->任务结束。

二、流程代码说明

1)流程发布

 //如果是读取默认的jbpm.cfg.xml文件   2 ProcessEngine engine = Configuration.getProcessEngine();  @b@  //如果不是读取默认的jbpm.cfg.xml文件   4 ProcessEngine engine = new Configuration()  @b@                 .setResource("ccjbpm.cfg.xml")  @b@                 .buildProcessEngine();  @b@  RepositoryService repositoryService = processEngine.getRepositoryService();  @b@  repositoryService.createDeployment()  @b@                 .addResourceFromClasspath("cn/javass/jbpm4/hello/hello.jpdl.xml")  @b@                .deploy();

2)流程定义

 ProcessEngine processEngine = Configuration.getProcessEngine();  @b@ RepositoryService repositoryService = processEngine.getRepositoryService();  @b@ List<ProcessDefinition> pdList = repositoryService.createProcessDefinitionQuery().list();  @b@ for (ProcessDefinition pd:pdList){  @b@ System.out.println("id:"+pd.getId());  @b@ System.out.println("name:"+pd.getName());  @b@ System.out.println("version:"+pd.getVersion());  @b@ System.out.println("deploymentId:"+pd.getDeploymentId());  @b@ System.out.println("---------------");  @b@}

3)启动实例

ProcessEngine processEngine = Configuration.getProcessEngine();  @b@ExecutionService executionService = processEngine.getExecutionService();  @b@Map map = new HashMap();  @b@map.put("pm","ProjectManager");  @b@map.put("dm", "DepartmentManager ");  @b@map.put("ceo", "Manager");  @b@executionService.startProcessInstanceByKey("MyProcess",map);

4)检索流程实例

ProcessEngine processEngine = Configuration.getProcessEngine();  @b@ExecutionService executionService = processEngine.getExecutionService();  @b@List<ProcessInstance> piList = executionService.createProcessInstanceQuery().list();  @b@for (ProcessInstance pi : piList) {  @b@System.out.println("id:"+pi.getId());  @b@System.out.println("activeActivityNames:“+pi.findActiveActivityNames());  @b@System.out.println("state:"+pi.getState());  @b@System.out.println("-----------------");

5)检索出Task

ProcessEngine processEngine = Configuration.getProcessEngine();  @b@TaskService taskService = processEngine.getTaskService();  @b@List<Task> list = taskService.createTaskQuery().list();  @b@for(Task t : list){  @b@  System.out.println("activityName="+t.getActivityName()+",user="  @b@                     +t.getAssignee()+",id="+t.getId()); @b@}

6) 完成task

ProcessEngine processEngine = Configuration.getProcessEngine();  @b@TaskService taskService = processEngine.getTaskService();  @b@String taskId = “70003”;//这个是流程运行中生成的任务id  @b@Map map = new HashMap();  @b@map.put("dmResult", 1);  @b@map.put("days", 15);  @b@taskService.completeTask(taskId,map);

7) 历史的流程实例

ProcessEngine engine = Configuration.getProcessEngine();  @b@HistoryService hs = engine.getHistoryService();  @b@List<HistoryProcessInstance> list = hs.createHistoryProcessInstanceQuery().list();  @b@for(HistoryProcessInstance hpi : list){  @b@    System.out.println("state="+hpi.getState()+" ,pdid=“+hpi.getProcessDefinitionId()+  @b@       ",piid="+hpi.getProcessInstanceId()+",startTime="+hpi.getStartTime());  @b@ }

三、流程描述

1)start(流程开始) 用于描述流程的开始节点,即流程从哪里开始,包含子节点transition,用来描述流程开始后的去向

2) end(流程结束) 用于描述该流程已经结束,包含子节点end-cancel和end-error表示流程结束原因

3)state(流程状态) 描述流程正处于等待外界的调用,与task不同的是他不会将任务分配给某个人 如果是同时只有单个state的情况,可以简单的使用: executionService.signalExecutionById(“这里默认使用流程实例的id"); 如果是同时有多个state的话,应该要先查找到Execution的id,如下使用:

ExecutionService exe =  engine.getExecutionService();  @b@Execution e = exe.createProcessInstanceQuery()  @b@                    .processInstanceId(piid).uniqueResult()  @b@                    .findActiveExecutionIn(“state活动名称");  @b@exe.signalExecutionById(e.getId());

4) decision(决策) 用于判断其中每一个transition元素的转移条件,当遇到一个transition的condition值为true的时候,就流向这个transition,decision活动的expr属性是一个三目运算符用来判断是否流向这个transition,decision活动的handler子元素,通过实现decisionHandler接口来在代码中决定要走向那个流程

方法一

 <decision name="evaluate document">  @b@      <handler class="org.jbpm.examples.decision.handler.ContentEvaluation" /> @b@      <transition name="good" to="submit document" /> @b@      <transition name="bad" to="try again" />  @b@      <transition name="ugly" to="give up" /> @b@ </decision>
public class ContentEvaluation implements DecisionHand  @b@    public String decide(OpenExecution execution) {  @b@      String content = (String) execution.getVariable("content");  @b@      if (content.equals("you're great")) {  @b@        return "good";  @b@      }  @b@      if (content.equals("you gotta improve")) {  @b@        return "bad";  @b@      }  @b@     return "ugly";  @b@   }  @b@ }

方法二

 <decision>  @b@      <transition name="good" to="submit document" /> @b@      <transition name="bad" to="try again" />  @b@      <transition name="ugly" to="give up" /> @b@ </decision>  @b@ @b@ Map<String, Object> variables = new HashMap<String, Object>();  @b@ variables.put("content", "good");  @b@  ProcessInstance processInstance = executionService.startProcessInstanceByKey("DecisionExpression", variables);

方法三

 <decision name="evaluate document">  @b@     <transition to="submit document">  @b@          <condition expr="#{content=="good"}" />  @b@     </transition>  @b@     <transition to="try again">  @b@          <condition expr="#{content=="not so good"}" />  @b@     </transition>  @b@     <transition to="give up" />  @b@ </decision>  @b@   @b@ Map<String, Object> variables = new HashMap<String, Object>();  @b@ variables.put("content", "good");  @b@ ProcessInstance processInstance =  @b@executionService.startProcessInstanceByKey("DecisionConditions", variables);

5) task(任务)一般用来处理涉及人机交互的活动,流程引擎会停在这里等待人工的操作。assignee属性:用来指定任务分配给谁(可以用变量定义){

<task name="review" assignee="#{order.owner}" > 《或者assignee="johndoe"》  @b@      <transition to="wait" />  @b@ </task>
public class Order implements Serializable {  @b@   @b@   String owner;  @b@   @b@   public Order(String owner) {  @b@   @b@     this.owner = owner;  @b@   @b@   }  @b@   @b@   public String getOwner() {  @b@   @b@     return owner;  @b@   @b@   }  @b@   @b@   public void setOwner(String owner) {  @b@   @b@     this.owner = owner;  @b@   @b@   }  @b@   @b@ }  @b@   @b@ Map<String, Object> variables = new HashMap<String, Object>();  @b@ variables.put("order", new Order("johndoe"));  @b@   @b@ ProcessInstance processInstance = executionService  @b@     .startProcessInstanceByKey("TaskAssignee", variables);  @b@   @b@ List<Task> taskList = taskService.findPersonalTasks("johndoe");  @b@ };

candidate-users属性:(可以用逗号分隔用户id列表)用来定义任务的候选人,用户想要接收这个任务需要人工的接受任务takeTask{

TaskService taskService = processEngine.getTaskService();@b@taskService.takeTask(“task的id”, “领取task的人员");

任务候选组candidate-groups:(类似于candidate-users){

 <task name="review" candidate-groups="sales" >  @b@   @b@      <transition to="wait" />  @b@   @b@ </task>  @b@   @b@ IdentityService identityService = processEngine.getIdentityService();  @b@ identityService.createGroup("sales");  @b@ identityService.createUser(“zhang", “zhang", “san");  @b@ identityService.createUser(“li", “li", “si");  @b@ identityService.createMembership(“zhang", "sales");  @b@ identityService.createMembership(“li", "sales");  @b@ taskService.findGroupTasks("zhang");  @b@ taskService.findGroupTasks("li");

注意:为了防止同一个任务被一个分组中的多个人领取,需要将这个任务分配给指定的个人后才能开始执行任务,例如下面

taskService.takeTask(task.getDbid(), "zhang");

并且任务呗某一个用户领取之后,应该将该任务标识为已领取状态,以避免造成重复。

任务分配器AssignmentHandler:支持使用java代码来进行任务分配{

<task name="review" g="96,16,127,52">  @b@ <assignment-handler class="org.jbpm.examples.task.assignmenthandler.AssignTask">  @b@   @b@       <field name="assignee">  @b@         <string value="johndoe" />  @b@       </field>  @b@   @b@ </assignment-handler>  @b@     <transition to="wait" />  @b@   @b@ </task>
public class AssignTask implements AssignmentHandler{  @b@   @b@ private String name;  @b@   @b@ public String getName() {  @b@   @b@ return name;  @b@   @b@ }  @b@   @b@ public void setName(String name) { this.name = name; }  @b@   @b@ public void assign(Assignable assignable, OpenExecution execution)  @b@   @b@ throws Exception {  @b@   @b@ assignable.setAssignee(name);  @b@   @b@     }  @b@   @b@ }

6) 并发(concurrency)包含join(合并分支)和fork(拆分分支)

7) java活动可以指定一个Java类的方法,当流程执行到此活动时,马上自动执行此Java方法。class属性用来指定此Java类的全类名,要注意这个类要有public无参的默认构造方法。method属性用来指定调用的方法。

var属性存储方法执行结果的流程变量名称。

 <java g="246,135,92,52" name="java1" class="cn.javass.test.java.MyJava"  @b@                         method="sayHello" var="manager">  @b@   @b@ <field name="user1"><object expr="#{user1}"/></field>  @b@   @b@ <field name="user2"><string value="user2"/></field>  @b@   @b@ <arg><string value="xyz"/></arg>  @b@   @b@ <arg><object expr="#{abc}"/></arg>  @b@   @b@ <transition to="task1"/>  @b@   @b@ </java>
 public class MyJava{  @b@   @b@ private String user1;  @b@   @b@ private String user2;  @b@   @b@ …user1和user2的setter  @b@   @b@ public String sayHello(String arg1,String arg2){  @b@   @b@ System.out.println("user1=="+user1);  @b@   @b@ System.out.println("user2=="+user2);  @b@   @b@ System.out.println("arg1=="+arg1);  @b@   @b@ System.out.println("arg2=="+arg2);  @b@   @b@ return “Hello";  @b@   @b@ }  @b@   @b@ }

8)script活动可以指定一个表达式,当流程执行到此活动时,马上自动执行此表达式,默认用的是juEL

9)sql活动能够支持使用sql直接从数据库中查询数据,并将结果返回到流程变量中。Xml代码

<sql g="192,438,92,52" name="sql1" unique="true" var="sqlV">  @b@ <query>  @b@ select * from tbl_user where uuid=:uuid  @b@ </query>  @b@   @b@ <parameters>  @b@ <object name="uuid" expr="#{uuid}"></object>  @b@ </parameters>  @b@   @b@ <transition to="hql1"/>  @b@ </sql>

10)hql活动能够支持使用hql直接从数据库中查询数据,并将结果返回到流程变量中。Xml代码

<hql name="hql1" g="404,457,92,52" unique="true" var="hqlV">  @b@ <query>  @b@ select o from Parent o where o.id=:id  @b@ </query>  @b@   @b@ <parameters>  @b@ <string name="id" value="22"/>  @b@ </parameters>  @b@   @b@ <transition to="task2"/>  @b@ </hql>
<foreach name="foreach1" in="D1,D2,D3" var="nowDep">  @b@ <transition to="task5"/>  @b@ </foreach>  @b@   @b@ <task name="task5">  @b@ <transition to="join1"/>  @b@ </task>  @b@   @b@ <join name="join1" multiplicity="3">  @b@ <transition to="task6"/>  @b@ </join>

11)foreach活动使得通过一条单独的流程路径来执行多条流程分支的功能in:将被迭代的集合。集合中的每个元素会生成一个新的同步分支。in执行任意类型的集合,数组和以逗号分隔的字符串。。var:用来保存集合中当前元素的变量。这个变量会设置到同步流程分支中,并且只对这个流程分支可见。

12)jBPM的事件机制使得我们可以很方便的在流程、活动、任务生命周期的各个阶段插入定制的代码逻辑,以便实现特定的业务逻辑操作。正是这种机制赋予了jBPM无限的可扩展性on活动:监听器在jpdl中可以被定为on活动。on活动的event属性{start|end}指明了监听器是在进入还是结束时触发<event-listener>、<java>、<sql>、<hql>等自动活动还可以作为<transition>元素的子元素,在流经这个<transition>的时候被执行。

<on event="start">  @b@   @b@     <event-listener class="org.jbpm.examples.eventlistener.LogListener">  @b@       <field name="msg"><string value="start on process definition"/></field>  @b@     </event-listener>  @b@  </on>  @b@   @b@   <start>  @b@     <transition to="wait"/>  @b@   </start>  @b@   @b@   <state name="wait">  @b@     <on event="start">  @b@       <event-listener class="org.jbpm.examples.eventlistener.LogListener">  @b@         <field name="msg"><string value="start on activity wait"/></field>  @b@       </event-listener>  @b@     </on>  @b@   @b@     <on event="end">  @b@       <event-listener class="org.jbpm.examples.eventlistener.LogListener">  @b@         <field name="msg"><string value="end on activity wait"/></field>  @b@       </event-listener>  @b@     </on>  @b@   @b@     <transition to="park">  @b@       <event-listener class="org.jbpm.examples.eventlistener.LogListener">  @b@         <field name="msg"><string value="take transition"/></field>  @b@       </event-listener>  @b@     </transition>  @b@   @b@ </state>
 public class MyEventListener implements EventListener{  @b@   @b@ public void notify(EventListenerExecution exection) throws Exception {  @b@   @b@ System.out.println("走出Decistion");  @b@   @b@   }  @b@ }

13)会签的概念1、概念:会签,又称会审,也就是流程中某个业务需要经过多人表决,并且根据表决意见的汇总结果,匹配设定的规则,决定流程的走向

另外:tomcat的配置:在将jBPM与web项目结合的时候,需要把jBPM资源包中的juel-engine.jar和juel-impl.jar添加到tomcat/lib下,同时在Web应用的lib下面,把juel-api.jar、juel-engine.jar和juel-impl.jar 删除掉