Jbpm3.2新手介绍
Java Business Process Management
jBpm 是一个功能强大的可扩展的工作流管理系统。
jBPM在2004年10月18日,发布了2.0版本,并在同一天加入了JBoss,成为了JBoss企业中间件平台的一个组成部分,它的名称也改成JBoss jBPM。随着jBPM加入JBoss组织,jBPM也将进入一个全新的发展时代,它的前景是十分光明的。
jBpm用流程语言来表示商业流程的术语比如:任务、异步通讯的等待状态、定时器、自动操作等等。把这些操作绑在一起, jBpm就有了强大和易扩展的控制流机制。
特点:
jBpm倚赖性很小,可以很容易的作为java库来使用。可以用在吞吐量极为关键的J2EE 群应用服务器环境中;
jBpm的持久化层用Hibernate实现,可以同任何数据库配置可以部署在任何应用服务器上。
jBpm工具箱;
jBpm图形化流程设计器:图形设计器是一个Eclipse插件;它同时支持业务分析员和技术开发人员,这样就可以在业务流程建模和实际执行之间平滑转换。
jBpm核心组件:是一个Java库;处理流程定义和运行时的流程实例执行。可以用在任何java环境(web应用程序,Swing应用程序,EJB等等)。
jBpm控制台web应用程序:流程执行运行时间任务生成的中央用户接口;管理和监视控制台允许检查和操作运行中的流程实例。
jBpm身份组件:身份验证。
jBpm调度程序:监视和运行已经计划到时执行流程的定时器的组件。
jBpm数据库兼容包:包括所有支持数据库的相关信息,JDBC驱动程序和数据库初始化脚本。
jBpm BPEL扩展:独立的扩展包用来支持BPEL(Business Process Execution Language 商业流程执行语言)
流程建模 基本概念(1):
流程定义:基于定向图表示了一个商业流程的规范。图由节点和转换组成,图中的每个节点都有一个特定的类型,节点类型定义了运行时的行为;流程定义有且只有一个开始状态。
流程实例:一个流程定义执行的实例,当一个流程实例被建立后,一个令牌也为主要执行路线建立了,这个令牌称为这个流程实例的根令牌,她的位置处于流程定义的开始状态。
令牌:
令牌:是执行的一个路线。令牌是运行时概念,用来维护指向图中某一节点的指针。
信号:
信号指示令牌继续图执行。当接受到无名的信号,令牌将用缺省的离开转换离开节点;当转换名字在信号中已经指定,令牌将使用指定的转换离开节点。
动作:
在流程执行中在事件上执行的片段java代码。主要事件类型是:(进入节点) entering a node,(离开节点) leaving a node?和(执行转换)taking a transition。
节点责任:
首先,它可以执行传统java代码;比如:建立一个新的任务实例、发送一个通知、更新数据库。
其次,使流程继续执行。
节点类型:
任务节点(task-node):任务型接点代表一个或多个可以被执行的任务,此类节点需要指定某个人执行;
等待节点(state):是一个单纯(bare-bones)等待状态,等待一个信号,信号到达到继续执行;
条件节点(decision):进行条件判断;
分支节点(fork):一个分支把一个执行路线分割成多个并发的执行路线;
联合节点(join):将多个并发路线合并成一个路线;
普通节点(node):当你想在节点里写入自己的代码时,可以使用普通节点。该类型节点无条件执行。
Transitions(转换):
转换具有一个源节点和一个目标节点;
转换可以有一个任意的名字,但必须是唯一的。
Actions(动作):
Action是一段代码,由流程中的时间触发
Action的代码:
public class RemoveEmployeeUpdate implements ActionHandler {
public void execute(ExecutionContext ctx) throws Exception {
??? //get the fired employee from the process variables.
??? String firedEmployee = (String)
?????? ctx.getContextInstance().getVariable("fired employee");???
??? Connection connection = ctx.getProcessInstance().
?????? getJbpmSession().getSession().getConnection();
??? Statement statement = connection.createStatement();??
??? statement.execute("DELETE FROM EMPLOYEE WHERE ...");
??? statement.execute();
??? statement.close();
}
}
jBPM设计器:
以插件的形式存在
插件安装:
1.将jbpm-designer文件夹复制任意目录下。
2.在<MyEclipse>\eclipse\links目录下创建jbpm-gpd.link文件,输入下面内容:
path=D:\\Program Files\\MyEclipse 6.0\\jbpm-designer\\jbpm-gpd-feature?????? (填入jbpm-gpd-feature的绝对目录即可)
概述(1)
流程定义代表业务流程的正式规范并且基于有向图。
图由节点和转换组成。
图中的每个节点指定类型。节点类型定义运行时行为。
一个流程定义绝对有一个开始状态。
概述(2)
令牌(token )是一个执行路径。一个令牌是维护图中一个节点指针的运行时概念。
流程实例是一个流程定义的执行。当一个流程实例被创建时,令牌为主执行路径创建。 这个令牌叫做流程实例的根令牌并且它被放在流程定义的开始状态上。
在令牌进入节点后,这个节点被执行。节点自己负责图执行连续。图执行连续完成后使令牌离开这个节点。每个节点类型为图执行连续实现 一个不同的行为。不传播执行的节点将成为状态节点。
流程图 :
流程定义的基础是由节点和转换组成的图。那信息被表达在一个叫prcessdefinition.xml 的xml文件中。每个节点都有一个类型,如状态、决策、分支、合并等等,每个节点都有 一系列的离开转换。为了区分开他们可以给转换一个名称。
task-node 节点:
任务(task )节点代表一个或多个将要被人们执行的任务。所以当执行到达任务节点时, 任务实例将在工作流参与者的任务列表中创建。
需要人们的参与该节点才会执行
state-node 节点:
状态(state)节点是一个最基本的等待状态。同任务节点的不同是不会在任何任务列表 中创建任务实例。
需要发送一个信号(Signal)该节点才会执行。
node节点:
无条件执行
decision 节点:
即为条件节点,根据不同的返回值决定流程的走向
实现方案:
定义一个实现DecisionHandler 接口的类
定义一个表达式#{ }
定义为<transition>指定<condition>子节点,指明条件
fork 节点:
分叉(fork)节点分开一个执行路径成为多个并发的执行路径。缺省的分叉行为是为每 个离开这个分叉节点的转换创建一个子令牌(token ),在到达分叉节点时生成和这个令牌的 一个父子关系(parent-child relation)。
join 节点:
缺省的,合并(join )假设所有到达合并节点的令牌是同一个父亲的孩子。这种情形被创建当使用上面所提及的分叉时创建同且当所有被分叉创建的令牌到达同一个合并时。一个 合并将结束每一个进入合并的令牌。当所有的兄弟令牌已经到达合并时,父令牌将通过“唯 一”的离开转换被传播。当仍然有兄弟令牌活动时,合并将扮演一个等待状态。
转换(transitions ):
转换(transitions )有一个源节点和一个目标节点。源节点代表来自(from)属性,目标节点代表到达(to )属性。
jBPM 的大部分属性依赖转换的命名的唯一性
动作(actions):
动作(actions)是在流程执行里的事件上执行的java 代码片段。
动作可以放在节点和事件上
放在节点上:可以影响控制流
放在事件上:不可以影响控制流
基本的API:
1.JbpmConfiguration:
jBPM流程实例的配置,在流程的执行过程中,需要使用JbpmConfiguration去创建需要的服务。
JbpmConfiguration是线程安全的对象,可以使用单例模式创建。
获取对象:
private static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance([jbpm.cfg.xml]);
主要方法:
public void createSchema(),生成存储数据的物理表
2.JbpmContext
用于流程的持久化操作。
得到JbpmContext对象
public JbpmContext getContext() {
JbpmContext jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
if (jbpmContext == null) {
jbpmContext = jbpmConfiguration.createJbpmContext();
}
return jbpmContext;
}
3.JbpmContext的主要方法
public void deployProcessDefinition(ProcessDefinition processDefinition)
发布流程定义,用于将流processdefinition.xml中的配置信息保存到数据库
public List getTaskList(String actorId)
获取指定用户的任务列表
public List getGroupTaskList(List actorIds)
获取指定用户组的任务列表
public TaskInstance loadTaskInstance(long taskInstanceId)
根据任务实例ID加载任务实例
public ProcessInstance loadProcessInstance(long processInstanceId)
根据ID加载流程实例
public ProcessInstance newProcessInstance(String processDefinitionName)
根据流程定义的名称创建最后一个版本的流程实例
public Session getSession()
获取Hibernate中的Session对象
public void setSession(Session session)
用新的Session代替原来的Session(Hibernate)
public Connection getConnection()
获取连接对象
public String getActorId()
获取当前ActorId
public void setActorId(String actorId)
设置新的ActorId
public void close()
关闭,该操作能将数据提交到数据库
4.ProcessDefinition
表示流程定义的对象模型
得到该对象的方法:
如果对象模型未存在:ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource(“simple/processdefinition.xml”);将流程定义的图模型转化成对象模型
如果对象模型已存在:ProcessDefinition processDefinition = JbpmContext.getGraphSession().findLatestProcessDefinition("simple");
如果是一zip文件:public static ProcessDefinition parseParZipInputStream(ZipInputStream zipInputStream),这个方法方便用户通过页面发布流程,发布后的数据保存在jbpm_bytearray表和jbpm_byteblock表中
5.ProcessInstance
流程实例
得到流程实例的两种方法
根据流程定义对象:ProcessInstance processInstance = new ProcessInstance(processDefinition)
根据流程定义名称:ProcessInstance processInstance = JbpmContext.newProcessInstance("simple")
根据ID获取流程实例:ProcessInstance processInstance = JbpmContext.getProcessInstance(id);
6.ProcessInstance的主要方法
public void signal():发送一个信号,对于state-node有效
public boolean hasEnded():判断流程实例是否有效
processInstance.getRootToken().getNode().getName():获取当前节点的名称
public long getId():获取流程实例的ID
7.TaskMgmtInstance
任务管理器实例,用于管理任务节点(task-node)
方法
public Collection getTaskInstances():获取管理的所有任务实例
8.TaskInstance
任务实例,需要人的参与
获取该对象
public TaskInstance loadTaskInstance(long taskInstanceId):根据任务实例ID加载任务实例
public List<TaskInstance> getTaskList(String actorId):获取指定用户所拥有的当前可用任务列表
public List<TaskInstance>?? getGroupTaskList(List actorIds):获取指定用户组所拥有的当前可用任务列表
9.TaskInstance的主要方法
public List<Transition> getAvailableTransitions():获取任务中可用的Transition集合
public void addVariables(Map variables):添加变量,变量在xml文件中配置
public Map getVariables():得到变量
public void end(Transition transition) public void end(String transitionName) public void end() 结束当前的任务并进入下一个节点
taskInstance.getTaskMgmtInstance().getProcessInstance():获取当前任务所在的流程实例
10.GraphSession
专门用于对流程定义和流程实例操作的Session
主要方法
public List findProcessInstances(long processDefinitionId):根据流程定义ID获取该流程的所有流程实例
public ProcessDefinition loadProcessDefinition(long processDefinitionId):根据ID加载流程定义
public ProcessDefinition findLatestProcessDefinition(String name):根据名字找到最后版本的流程定义
public List findAllProcessDefinitions():找到所有的流程定义
public void deleteProcessDefinition(long processDefinitionId):根据ID删除流程定义
public ProcessInstance loadProcessInstance(long processInstanceId):根据ID加载流程实例
11.TaskMgmtSession
管理任务的Session
方法
public List findTaskInstances(String actorId):查找指定用户的任务实例列表
public List findTaskInstances(String[] actorIds):查找多个用户的任务实例列表
public List findPooledTaskInstances(String actorId):一个任务分配给多个执行人时使用
public List findPooledTaskInstances(List actorIds):同上
public TaskInstance loadTaskInstance(long taskInstanceId):根据ID获取任务实例
public List findTaskInstancesByIds(List taskInstanceIds):同上,但是可以指定多个ID
基本操作
实现思路:
1、根据配置信息创建各种服务和对象
2、获取jbpm上下文
3、发布流程[每次修改流程后都要执行执行]
4、驱动节点
5、处理任务
一个流程定义包含多个流程实例,一个流程实例包含一个任务管理器,一个任务管理器包含了所有任务实例。
参见:http://hi.baidu.com/suny_duan/blog/item/bdefc30ecca6dd246159f376.html
数据处理
1、流程数据
每一个流程实例都能保存相关数据,这些数据与指定流程绑定
将数据与流程实例绑定
ProcessInstance.setContextInstance(“名称”,”值”)
从流程实例中读取数据
ProcessInstance.getContextInstance(“名称”)
2.任务数据
可以为每个任务实例绑定相关数据,并为数据指定访问权限
访问权限有:
read,required
read,write,required
read,write
read
write
3、业务数据
业务数据是与业务逻辑相关的数据,比如请假数据,报销数据。
业务数据往往要和流程数据或任务数据建立连接。保存业务数据的ID即可。
常见接口:
1.ActionHandler:
org.jbpm.graph.def.ActionHandler
定义一个自定义动作类,实现该接口即可
方法
public void execute(ExecutionContext context) throws Exception {
System.out.println("审批完毕!");
}
2.AssignmentHandler:
org.jbpm.taskmgmt.def.AssignmentHandler
为任务指定执行人
方法
public void assign(Assignable assignable, ExecutionContext executionContext)throws Exception {
assignable.setActorId("张三");//指定一个执行人
assignable.setPooledActors(new String[]{"李四", "王八"});//指定一组执行人
}
3.DecisionHandler:
org.jbpm.graph.node.DecisionHandler
自定义条件类,在<decision><handler class=“”></handler></ decision>中指定
方法
public String decide(ExecutionContext executionContext) throws Exception {
if(true){
return "执行路径1";
}else{
return "执行路径2";
}
}
?转自:http://hi.baidu.com/suny_duan/blog/item/7389ba352ffa09355ab5f570.html