为什么需要工作流管理系统
使用jbpm带来的好处
1、把某些容易变化的部分,能够抽象出来,通过某种方式改变它
2、jbpm主要是用来从一个用户手上转递给另外一个用户的
3、jbpm工作引擎:定义流程,执行流程
工作流管理系统的构成
1、工作流引擎(核心):定义流程,执行流程
2、工作流设计器:目的是定义流程(例:绘流程图)。另外可以使用flex设计开发设计器
3、流程操作:流程引擎提供的API然后去调用,包括启动流程、结束流程、挂起流程、查询流程
4、工作流客户端程序:把工作流引擎集成到OA当中,OA系统则相当于工作流客户端程序。
5、流程监控:对系统里面运行有哪些流程,以及流程流转到哪些地方,对流程做一些其它操作等
6、表单设计器:在系统部署完成后,可灵活的创建新的流程
7、与表单的集成:
8、与应用程序的集成:比如到达某一环节时需要有额外的工作,这种情况下需要与应用程序集成。jbpm中会提供相关方法
不使用jbpm
1、如果没有应用工作流引擎技术,逻辑写死在业务代码中了
2、提交请假单时的方法需要(请假单位ID,提交者ID)
{
if请假单是新建的then设置审批者为张三
if提交者是张三 and 请假单已审批通过 then 设置审批者为李四
if提交者是李四 and 请假单已审批通过 then 请假流程结束
}
3、如果用户有变化(定义一个规则)可通过配置文件来获取用户(类似JDBC的连接)然后业务代码需要的对象可从配置文件获取
4、或者在流程当中的环节有变化(根据条件有可能经过有可能不经过(大于一天、小于一天)),则需要定义一个规则,定义规则之后还需要对规则进行解释
5、如果没有配置规则,则代码量非常大,而且维护起来也比较麻烦
例如:一个请假单流程
1、流程的本质是由多个参与者形成的,会参与到一个流程当中这就是所谓的流程
2、jbpm主要是用来从一个用户手上转递给另外一个用户的
JBPM的基本流程概念
1、jbpm定义流程是一种规则的定义,基于用UML里面的活动图(流程图)来定义流程的。ProcessDefintion
2、结点
1、startNode、endNode是一种伪状态结点,startNode不允许有arrivingTranstion(进入),endNode不允许有learingTrantion(离开)
2、State:状态节点,表示一种等待状态,在此节点中规定要做的事件,比如发邮件等。
3、Fork、join是成对出现的主要完成同步工作流的定义,Fork分开、join连接
4、Decision:完成条件流转的定义,例根据表达式计算结果,根据结果执行不同的流转,它是一种自动节点
5、taskNode:任务节点,通常表示一个流程的环节,(任务:由某些事件需要由某些人去做)主要用来完成任务分配的定义
JBPM流程实例执行的概念
1、流程实例是按照某个规则来流转的具体的信息或者是一个流程创建的一个对象,例如,张三的请假单就是一个流程实例,一个流程包含多少实例
2、流程实例携带的信息称为流程实例变量包括(请假者,请假天数等等),流程实例变量存放在ContextInstance,创建流程实例的时候JBPM自动创建一个ContextInstance对象,可以理解为是一个变量的容器。例如:setVarible(String name,Object value),(String)getVarible(String name)
3、创建某一个单据的时候就是创建流程实例的时候
Jbmp的核心调试过程,如何实现流转(pathnet)
1、在创建流程实例的时候,JBPM会自动创建一个跟它对应的Token对象(rootToken),一个流程实例只能有一个rootToken,Token有一个引用指向一个节点,然后调用流程实例的singnal()方法就能够触发Token把引用指向下一节点。Token最初是指向start节点的,指向的改变就是流程执行的意思。rootToken是一个树形结构
2、Jbmp的核心调试过程也就是在调用processInstance.singnal()方法的时候发生了什么
1、如何找到rootToken指向的下一节点:
1、调用leave()方法,会抛出node leave事件
2、调用singal(String transitionName)方法,指定transitionName,则按照指定的transition离开,否则,将随机选择一个transtion离开
3、找到transtion之后调用take()方法,会抛出transition事件
4、找到to node之后调用enter()方法,会抛出node enter事件
5、然后将Token指向的节点修改为自身
6、最后执行execute();是这个节点的行为的体现
如何实现多人会签,而且只要其中一个人审批通过就继续往下?
- 实现方法1:利用pooled-actors,可以使用pooled-actors定义多个参与者,
并使用findPooledTaskInstances来查找任务实例,其中任意一个人审批通过
并提交之后,其它人将看不到这个任务实例(参考complex_051)
- 实现方法2:在同一个TaskNode节点中定义多个Task,并设置signal="first"(参考complex_06)
1. last - 默认,最后一个任务实例被结束时执行继续;
如果Task-Node下面根本没有定义Task,则执行继续
2. last-wait - 最后一个任务实例被结束时,执行继续
如果Task-Node下面根本没有定义Task,则等待
3. first - 第一个任务实例被结束时,执行继续
如果Task-Node下面根本没有定义Task,则执行继续
4. first-wait - 第一个任务实例被结束时,执行继续
如果Task-Node下面根本没有定义Task,则等待
5. never - 执行永远不会继续(即通过TaskInstance.end操作不会触发流程往下走)
6. unsynchronized - 直接往下执行(signal),不管是否有任务实例
本项目主要测试:如何给角色分配任务?
- 实现AssignmentHandler接口,在接口的实现方法中,查询角色下面的用户,并
将任务实例分配给这些用户即可。(参考complex_07以及RoleAssignmentHandler01.java)
思考:如何实现提交给本部门的部门领导审批?
根据公文ID----得到公文创建者---得到对应的user---得到所属部门(参考complex_07_02以及RoleAssignmentHandler02.java)
描述各种在Handler中获取spring的bean的方法,描述JbpmHandlerProxy解决方案,及其不足之处
- BeanFactoryAware的用法:
- 如何利用BeanFactoryAware来获取BeanFactory:一个类需要实现BeanFactoryAware接口,同时实现setBeanFactory();//这个接口不常用
- JbpmHandlerProxy的基本原理:spring第三方控件,支持继承用这个类,它本身已经实现了ActionHandler, AssignmentHandler, DecisionHandler, TaskControllerHandler实现过程给封装起来了,与客户端和服务端相连
- 利用JbpmHandlerProxy的机制来获取BeanFactory
- 进一步封装,并利用AutowireCapableBeanFactory来自动注入依赖对象