关于JBPM工作流

  1. 2.        JBPM

jBPM,全称是Java Business Process Management,是一种基于J2EE的轻量级工作流管理系统。JBPM使用Hibernate进行数据库操作,也就是说只要Hibernate支持的数据库它都可以使用,数据库主要是存放流程的定义,流程实例的信息,还有用户的信息等。

Jbpm工作流适用于:

n  项目流程比较多,流程复杂的项目。

n  系统运行和维护、升级时,流程可能需要修改、调整和跟踪、控制的项目。

1、JBPM4表说明:
JBPM4_DEPLOYMENT   流程定义表
JBPM4_DEPLOYPROP 流程定义属性表
JBPM4_EXECUTION  流程实例表
JBPM4_HIST_ACTINST 流程活动( 节点) 实例表
JBPM4_HIST_DETAIL  流程历史详细表
JBPM4_HIST_PROCINST 流程实例历史表
JBPM4_HIST_TASK  流程任务实例历史表
JBPM4_HIST_VAR  流程变量( 上下文) 历史表
JBPM4_ID_GROUP 组表
JBPM4_ID_MEMBERSHIP 用户角色表
JBPM4_ID_USER  用户表
JBPM4_JOB  定时表
JBPM4_LOB  存储表  存放流程定义的xml和png图片文件
JBPM4_PARTICIPATION 参与者表
JBPM4_SWIMLANE  泳道表
JBPM4_TASK 任务表
JBPM4_VARIABLE 上下文表
 
jBPM4.4的数据库表分成以下几类: 
1)和系统相关:这个只有JBPM4_PROPERTY 
2)和ProcessDefinition相关的表:JBPM4_DEPLOYMENT、JBPM4_DEPLOYPROP、JBPM4_LOB 
3)和开启一个instance相关:  有JBPM4_EXECUTION、JBPM4_TASK、JBPM4_JOB、JBPM4_VARIABLE、JBPM4_SWIMLANE、 JBPM_PARTICIPATION 
4)和历史相关的表:  JBPM4_HIS_ACTINST、JBPM4_HIS_DETAIL、JBPM4_HIS_PROCINST、JBPM4_HIS_TASK、JBPM4_HIS_VAR 
5)和用户/组相关的表有:  JBPM4_ID_USER、JBPM4_ID_GROUP、JBPM4_ID_MEMBERSHIP 具体数据库的详细数据结果可以参看,随文所附的jbpm.pdm文件,使用powerdesigner打开。
 
2、工作流的基本思路:
2.1 、描述工作流
2.2 、发布和存储工作流
2.3 、装载和解析工作流
2.4 、顶层对象:流程、活动、转移
2.5 、流程定义和流程实例
2.6 、活动定义和活动实例
2.7 、令牌驱动,petri网
2.8 、转移:隐式、显示、fork(分支)、join、按条件等等
2.9 、活动:人工活动、自动活动等
2.10、人工活动会涉及:活动的处理页面、活动的数据
2.11、workList:活动的列表、接收、拒收、重分配、活动的响应等
 
3、jBPM有什么,简介jBPM的Service API
1:ProcessEngine:流程引擎。并不负责具体的业务,而是用于获取各种Service。
2:RepositoryService:流程资源服务的接口,如流程定义发布、查询、删除等。
{
    在流程仓库里包含部署管理、
}
3:ExecutioService:用于操作流程实例的服务,可以进行流程实例发布、查询、流程推进、设置流程变量等操作。
4:TaskService:用于操作人工任务的服务,可以进行任务创建、查询、获取、提交完成、保存、删除等操作。
5:HistoryService:用于操作流程历史的服务,提供对流程历史库(就是已经完成的流程实例)的操作。比如:历史流程实例,历史活动实例等。
6:IdentityService:用于操作用户、用户组以及成员关系的服务
7:ManagementService:流程管理控制服务的接口,只提供异步工作(Job)相关的执行和查询操作。
 
4、jPDL基础--1

全称是jBoss jPBM Process Definition Language,这种一种构建于jBPM架构之上的流程语言之一。jPDL提供了图形化处理的界面,跟VB语言差不多,拖拖拽拽就能做出个东西来,非常直观。这里面提供了很多图形化节点:

start和end节点在每个jBPM项目中都会用到,分别为开始节点和结束节点;

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

  1. //如果是读取默认的jbpm.cfg.xml文件
  2. ProcessEngine engine = Configuration.getProcessEngine();
  3. //如果不是读取默认的jbpm.cfg.xml文件
  4. ProcessEngine engine = new Configuration()
  5. .setResource("ccjbpm.cfg.xml")
  6. .buildProcessEngine();
  7. RepositoryService repositoryService = processEngine.getRepositoryService();
  8. repositoryService.createDeployment()
  9. .addResourceFromClasspath("cn/javass/jbpm4/hello/hello.jpdl.xml")
  10. .deploy();
2、如何检索流程定义
  1. ProcessEngine processEngine = Configuration.getProcessEngine();
  2. RepositoryService repositoryService = processEngine.getRepositoryService();
  3. List<ProcessDefinition> pdList = repositoryService.createProcessDefinitionQuery().list();
  4. for (ProcessDefinition pd:pdList){
  5. System.out.println("id:"+pd.getId());
  6. System.out.println("name:"+pd.getName());
  7. System.out.println("version:"+pd.getVersion());
  8. System.out.println("deploymentId:"+pd.getDeploymentId());
  9. System.out.println("---------------");
  10. }
3、如何启动一个实例
  1. ProcessEngine processEngine = Configuration.getProcessEngine();
  2. ExecutionService executionService = processEngine.getExecutionService();
  3. Map map = new HashMap();
  4. map.put("pm","ProjectManager");
  5. map.put("dm", "DepartmentManager ");
  6. map.put("ceo", "Manager");
  7. executionService.startProcessInstanceByKey("MyProcess",map);
4、如何检索流程实例
  1. ProcessEngine processEngine = Configuration.getProcessEngine();
  2. ExecutionService executionService = processEngine.getExecutionService();
  3. List<ProcessInstance> piList = executionService.createProcessInstanceQuery().list();
  4. for (ProcessInstance pi : piList) {
  5. System.out.println("id:"+pi.getId());
  6. System.out.println("activeActivityNames:“+pi.findActiveActivityNames());
  7. System.out.println("state:"+pi.getState());
  8. System.out.println("-----------------");
5、如何检索出Task
  1. ProcessEngine processEngine = Configuration.getProcessEngine();
  2. TaskService taskService = processEngine.getTaskService();
  3. List<Task> list = taskService.createTaskQuery().list();
  4. for(Task t : list){
  5. System.out.println("activityName="+t.getActivityName()+",user="
  6. +t.getAssignee()+",id="+t.getId());
6、如何完成task
  1. ProcessEngine processEngine = Configuration.getProcessEngine();
  2. TaskService taskService = processEngine.getTaskService();
  3. String taskId = “70003”;//这个是流程运行中生成的任务id
  4. Map map = new HashMap();
  5. map.put("dmResult", 1);
  6. map.put("days", 15);
  7. taskService.completeTask(taskId,map);
7、如何检索出历史的流程实例
  1. ProcessEngine engine = Configuration.getProcessEngine();
  2. HistoryService hs = engine.getHistoryService();
  3. List<HistoryProcessInstance> list = hs.createHistoryProcessInstanceQuery().list();
  4. for(HistoryProcessInstance hpi : list){
  5. System.out.println("state="+hpi.getState()+" ,pdid=“+hpi.getProcessDefinitionId()+
  6. ",piid="+hpi.getProcessInstanceId()+",startTime="+hpi.getStartTime());
  7. }
6、流程的描述
1、start(流程开始) 用于描述流程的开始节点,即流程从哪里开始,包含子节点transition,用来描述流程开始后的去向
2、end(流程结束) 用于描述该流程已经结束,包含子节点end-cancel和end-error表示流程结束原因
3、state(流程状态) 描述流程正处于等待外界的调用,与task不同的是他不会将任务分配给某个人
如果是同时只有单个state的情况,可以简单的使用:
executionService.signalExecutionById(“这里默认使用流程实例的id");
如果是同时有多个state的话,应该要先查找到Execution的id,如下使用:
  1. ExecutionService exe =  engine.getExecutionService();
  2. Execution e = exe.createProcessInstanceQuery()
  3. .processInstanceId(piid).uniqueResult()
  4. .findActiveExecutionIn(“state活动名称");
  5. exe.signalExecutionById(e.getId());
4、decision(决策) 用于判断其中每一个transition元素的转移条件,当遇到一个transition的condition值为true的时候,就流向这个transition,decision活动的expr属性是一个三目运算符用来判断是否流向这个transition,decision活动的handler子元素,通过实现decisionHandler接口来在代码中决定要走向那个流程
方法一:
  1. <decision name="evaluate document">
  2. <handler class="org.jbpm.examples.decision.handler.ContentEvaluation" />
  3. <transition name="good" to="submit document" />
  4. <transition name="bad" to="try again" />
  5. <transition name="ugly" to="give up" />
  6. </decision>
  1. public class ContentEvaluation implements DecisionHand
  2. public String decide(OpenExecution execution) {
  3. String content = (String) execution.getVariable("content");
  4. if (content.equals("you're great")) {
  5. return "good";
  6. }
  7. if (content.equals("you gotta improve")) {
  8. return "bad";
  9. }
  10. return "ugly";
  11. }
  12. }
方法二:
  1. <decision>
  2. <transition name="good" to="submit document"  />
  3. <transition name="bad"  to="try again"  />
  4. <transition name="ugly" to="give up"  />
  5. </decision>
  6. Map<String, Object> variables = new HashMap<String, Object>();
  7. variables.put("content", "good");
  8. ProcessInstance processInstance =
  9. executionService.startProcessInstanceByKey("DecisionExpression", variables);
方法三:
  1. <decision name="evaluate document">
  2. <transition to="submit document">
  3. <condition expr="#{content=="good"}" />
  4. </transition>
  5. <transition to="try again">
  6. <condition expr="#{content=="not so good"}" />
  7. </transition>
  8. <transition to="give up" />
  9. </decision>
  10. Map<String, Object> variables = new HashMap<String, Object>();
  11. variables.put("content", "good");
  12. ProcessInstance processInstance =
  13. executionService.startProcessInstanceByKey("DecisionConditions", variables);
5、task(任务)一般用来处理涉及人机交互的活动,流程引擎会停在这里等待人
工的操作。
assignee属性:用来指定任务分配给谁(可以用变量定义){
  1. <task name="review" assignee="#{order.owner}" > 《或者assignee="johndoe"》
  2. <transition to="wait" />
  3. </task>
  4. public class Order implements Serializable {
  5. String owner;
  6. public Order(String owner) {
  7. this.owner = owner;
  8. }
  9. public String getOwner() {
  10. return owner;
  11. }
  12. public void setOwner(String owner) {
  13. this.owner = owner;
  14. }
  15. }
  16. Map<String, Object> variables = new HashMap<String, Object>();
  17. variables.put("order", new Order("johndoe"));
  18. ProcessInstance processInstance = executionService
  19. .startProcessInstanceByKey("TaskAssignee", variables);
  20. List<Task> taskList = taskService.findPersonalTasks("johndoe");
};
candidate-users属性:(可以用逗号分隔用户id列表)用来定义任务的候选人,用户想要接收这个任务需要人工的接受任务takeTask{
TaskService taskService = processEngine.getTaskService();
taskService.takeTask(“task的id”, “领取task的人员");
};
任务候选组candidate-groups:(类似于candidate-users){
  1. <task name="review" candidate-groups="sales" >
  2. <transition to="wait" />
  3. </task>
  4. IdentityService identityService = processEngine.getIdentityService();
  5. identityService.createGroup("sales");
  6. identityService.createUser(“zhang", “zhang", “san");
  7. identityService.createUser(“li", “li", “si");
  8. identityService.createMembership(“zhang", "sales");
  9. identityService.createMembership(“li", "sales");
  10. taskService.findGroupTasks("zhang");
  11. taskService.findGroupTasks("li");
注意:为了防止同一个任务被一个分组中的多个人领取,需要将这个任务分配给指定的个人后才能开始执行任务,例如下面
taskService.takeTask(task.getDbid(), "zhang");并且任务呗某一个用户领取之后,应该将该任务标识为已领取状态,以避免造成重复。
};
任务分配器AssignmentHandler:支持使用java代码来进行任务分配{
  1. <task name="review" g="96,16,127,52">
  2. <assignment-handler class="org.jbpm.examples.task.assignmenthandler.AssignTask">
  3. <field name="assignee">
  4. <string value="johndoe" />
  5. </field>
  6. </assignment-handler>
  7. <transition to="wait" />
  8. </task>
  9. public class AssignTask implements AssignmentHandler{
  10. private String name;
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) { this.name = name; }
  15. public void assign(Assignable assignable, OpenExecution execution)
  16. throws Exception {
  17. assignable.setAssignee(name);
  18. }
  19. }
注意:Please note that potentially, AssignmentHandler implementations can use the process variables and any other Java API to access resources like your application database to calculate the assignee and candidate users and groups.
}
6、并发(concurrency)包含join(合并分支)和fork(拆分分支)
7、java活动可以指定一个Java类的方法,当流程执行到此活动时,马上自动执行此Java方法。
class属性用来指定此Java类的全类名,要注意这个类要有public无参的默认构造方法。
method属性用来指定调用的方法。
var属性存储方法执行结果的流程变量名称。
  1. <java g="246,135,92,52" name="java1" class="cn.javass.test.java.MyJava"
  2. method="sayHello" var="manager">
  3. <field name="user1"><object expr="#{user1}"/></field>
  4. <field name="user2"><string value="user2"/></field>
  5. <arg><string value="xyz"/></arg>
  6. <arg><object expr="#{abc}"/></arg>
  7. <transition to="task1"/>
  8. </java>
  9. public class MyJava{
  10. private String user1;
  11. private String user2;
  12. …user1和user2的setter
  13. public String sayHello(String arg1,String arg2){
  14. System.out.println("user1=="+user1);
  15. System.out.println("user2=="+user2);
  16. System.out.println("arg1=="+arg1);
  17. System.out.println("arg2=="+arg2);
  18. return “Hello";
  19. }
  20. }
8、script活动可以指定一个表达式,当流程执行到此活动时,马上自动执行此表达式,默认用的是juEL
9、sql活动能够支持使用sql直接从数据库中查询数据,并将结果返回到流程变量中。
  1. <sql g="192,438,92,52" name="sql1" unique="true" var="sqlV">
  2. <query>
  3. select * from tbl_user where uuid=:uuid
  4. </query>
  5. <parameters>
  6. <object name="uuid" expr="#{uuid}"></object>
  7. </parameters>
  8. <transition to="hql1"/>
  9. </sql>
10、hql活动能够支持使用hql直接从数据库中查询数据,并将结果返回到流程变量中。
  1. <hql name="hql1" g="404,457,92,52" unique="true" var="hqlV">
  2. <query>
  3. select o from Parent o where o.id=:id
  4. </query>
  5. <parameters>
  6. <string name="id" value="22"/>
  7. </parameters>
  8. <transition to="task2"/>
  9. </hql>
11、foreach活动使得通过一条单独的流程路径来执行多条流程分支的功能
in:将被迭代的集合。集合中的每个元素会生成一个新的同步分支。in执行任意类型的集合,数组和以逗号分隔的字符串。。
var:用来保存集合中当前元素的变量。这个变量会设置到同步流程分支中,并且只对这个流程分支可见。
与join活动连用
通常情况下,foreach活动后面是多次执行的活动,在这个活动后面应该跟一个join活动,并且把join活动的multiplicity设置成为foreach的数量,这样才会等到foreach的多个task执行完成,流程才继续向下,否则,只要有一个foreach的task完成了,流程就向下流转了。
  1. <foreach name="foreach1" in="D1,D2,D3" var="nowDep">
  2. <transition to="task5"/>
  3. </foreach>
  4. <task name="task5">
  5. <transition to="join1"/>
  6. </task>
  7. <join name="join1" multiplicity="3">
  8. <transition to="task6"/>
  9. </join>
12、jBPM的事件机制使得我们可以很方便的在流程、活动、任务生命周期的各个阶段插入定制的代码逻辑,以便实现特定的业务逻辑操作。正是这种机制赋予了jBPM无限的可扩展性
on活动:监听器在jpdl中可以被定为on活动。
on活动的event属性{start|end}指明了监听器是在进入还是结束时触发<event-listener>、<java>、<sql>、<hql>等自动活动还可以作为<transition>元素的子元素,在流经这个<transition>的时候被执行。
  1. <on event="start">
  2. <event-listener class="org.jbpm.examples.eventlistener.LogListener">
  3. <field name="msg"><string value="start on process definition"/></field>
  4. </event-listener>
  5. </on>
  6. <start>
  7. <transition to="wait"/>
  8. </start>
  9. <state name="wait">
  10. <on event="start">
  11. <event-listener class="org.jbpm.examples.eventlistener.LogListener">
  12. <field name="msg"><string value="start on activity wait"/></field>
  13. </event-listener>
  14. </on>
  15. <on event="end">
  16. <event-listener class="org.jbpm.examples.eventlistener.LogListener">
  17. <field name="msg"><string value="end on activity wait"/></field>
  18. </event-listener>
  19. </on>
  20. <transition to="park">
  21. <event-listener class="org.jbpm.examples.eventlistener.LogListener">
  22. <field name="msg"><string value="take transition"/></field>
  23. </event-listener>
  24. </transition>
  25. </state>
  26. public class MyEventListener implements EventListener{
  27. public void notify(EventListenerExecution exection) throws Exception {
  28. System.out.println("走出Decistion");
  29. }
  30. }
13、会签的概念
1、概念:会签,又称会审,也就是流程中某个业务需要经过多人表决,并且根据表决意见的汇总结果,匹配设定的规则,决定流程的走向
7、tomcat的配置:
在将jBPM与web项目结合的时候,需要把jBPM资源包中的juel-engine.jar和juel-impl.jar添加到tomcat/lib下,同时在Web应用的lib下面,把juel-api.jar、juel-engine.jar和juel-impl.jar 删除掉
 

JBPM4 学习笔记 转的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

随机推荐

  1. 使用npm发布、查看、引用、删除自己的包[小白推荐]

    前言  怎么使用npm发布自己的组件包呢?博主看了不少相关的文章,都没有一个好的讲述.要么丢三落四,要么就是复杂到外行人根本看不懂,甚至无从下手.于是,在博主的潜心钻研下,终于成功了!所以,我打算写一 ...

  2. Spring 依赖注入原理

    所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它.所以我们只需从容器直接获取Bean对象就行, ...

  3. Codeforces 1062B Math(质因数分解)

    题意: 给一个数n,可以将它乘任意数,或者开方,问你能得到的最小数是多少,并给出最小操作次数 思路: 能将这个数变小的操作只能是开方,所以构成的最小数一定是 $n = p_1*p_2*p_3*\dot ...

  4. webpack chunkFilename 非入口文件的命名规则 [转]

    官网的文档只理解了filename是主入口的文件名,chunkFilename是非主入口的文件名 filename应该比较好理解,就是对应于entry里面生成出来的文件名.比如: { entry: { ...

  5. [MP3]MP3固件持续分享(2019.1.25)

    转载自我的博客:https://blog.ljyngup.com/archives/179.html/ 所有的固件到我的博客就可以下载哦 最后更新于2019.2.1 前言 这篇文章会持续更新不同型号的 ...

  6. Part1-解线性方程组

    自己一边听课一边记得,参考网上广为流传的那本<MIT线性代数笔记>,转成Latex上传太麻烦,直接截图上传了,需要电子版的可以私信我.

  7. JVM解毒——类加载子系统

    带着问题,尤其是面试问题的学习才是最高效的.加油,奥利给! 点赞+收藏 就学会系列,文章收录在 GitHub JavaEgg ,N线互联网开发必备技能兵器谱 直击面试 看你简历写得熟悉JVM,那你说说 ...

  8. [WPF 自定义控件]在MenuItem上使用RadioButton

    1. 需求 上图这种包含多选(CheckBox)和单选(RadioButton)的菜单十分常见,可是在WPF中只提供了多选的MenuItem.顺便一提,要使MenuItem可以多选,只需要将MenuI ...

  9. light oj 1214 - Large Division 大数除法

    1214 - Large Division Given two integers, a and b, you should check whether a is divisible by b or n ...

  10. Arm开发板+Qt学习之路-开发板显示 /bin/sh: ./hello: Permission denied

    将pc上交叉编译完成的可执行文件hello,通过串口传输到开发板上后,执行./hello显示 /bin/sh: ./hello: Permission denied 解决方案:在开发板上执行  chm ...