JBPM5学习资料(资源)
快速开始
首先下载jBPM,http://sourceforge.net/projects/jbpm/files/
可以有选择性的下载:
一些有用的链接
源码
jBPM的,现在使用它的源代码版本控制系统的git。可以在这里找到jBPM项目的来源(包括所有版本从jBPM5.0- CR1开始):
https://github.com/droolsjbpm/jbpm
安装所需条件
JDK 1.5+ (set as JAVA_HOME)
Ant 1.7+
演示环境安装
到安装目录下运行
ant install.demo
将会执行
如果你想看到报告在jBPM控制台上,那么需要修改build.properties文件的jBPM.birt.download属性设置为true
ant start.demo
启动示例
使用Eclipse tools
导入示例工程下的sample/evaluation
导入之后可以看到工程中的示例程序
双击打开Evaluation.bpmn
可以运行ProcessTest进行测试
使用jBPM控制台
启动后输入如下链接
http://localhost:8080/jbpm-console
使用 krisv / krisv 登录
可以看到如下界面
你可以启动一个新的流程,查看一个正在运行的流程的实例的状态,查看你的任务,完成任务,监控流程的执行
使用Guvnor仓库和设计
作为一个过程库的Guvnor库可用于存储业务流程。它还提供了一个基于Web的界面来管理您的进程。
输入如下地址可以进入
http://localhost:8080/drools-guvnor
核心引擎API
本节介绍的API,你需要加载过程并执行它们。对于如何界定的过程本身更详细,查看检出的BPMN 2.0的章节。
你可以在知识库中定义一个流程实例,然后在知识库中产生一个实例的session对象,如下图所示
知识库可以共享会话之间,通常只创建一次,在启动应用程序。知识库可以动态改变(这样你就可以在运行过程中添加或删除)。
会话可以创建基于一个知识库,用于执行过程,并与引擎交互。你想创建一个会话被认为是相对较轻的,你可以创造尽可能多的独立会议。如何创建许多会议是由你。在一般情况下,最简单的情况下开始创建一个会话,然后在您的应用程序的各个地方。你可以决定创建多个会话,例如,如果你想有多个独立的处理单元(例如,你想要的所有进程,从一个客户的完全独立于另一个客户的过程,使您可以创建一个为每个客户独立会议),或如果你需要多个会话,可扩展性的原因。如果你不知道做什么,只要简单地启动一个知识库,其中包含你所有的流程定义和创建会话,然后使用执行你所有的流程。
正如上文所述,jBPM的API,因此可用于:(1)创建一个知识库,其中包含您的流程定义(2)创建一个会话启动新的进程实例,信号现有注册侦听等。
1)知识库
通过知识库加载流程定义,通过以下代码实现
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource(
"MyProcess.bpmn"
), ResourceType.BPMN2);
KnowledgeBase kbase = kbuilder.newKnowledgeBase();
|
ResourceFactory有类似的方法来加载文件系统的文件,从URL,InputStream中,等
2)Session
一旦你加载你的知识库,你应该创建一个会话与引擎交互。本次会议可以被用来启动新的进程,信号事件等,下面的代码片段显示了它是多么容易创建较早创建的知识库为基础的会话,并启动一个进程(ID)。
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
ProcessInstance processInstance = ksession.startProcess(
"com.sample.MyProcess"
);
|
ProcessRuntime接口定义了所有的会议方法与流程交互,如下所示。
/**
* Start a new process instance. The process (definition) that should
* be used is referenced by the given process id.
*
* @param processId The id of the process that should be started
* @return the ProcessInstance that represents the instance of the process that was started
*/
ProcessInstance startProcess(String processId);
/**
* Start a new process instance. The process (definition) that should
* be used is referenced by the given process id. Parameters can be passed
* to the process instance (as name-value pairs), and these will be set
* as variables of the process instance.
*
* @param processId the id of the process that should be started
* @param parameters the process variables that should be set when starting the process instance
* @return the ProcessInstance that represents the instance of the process that was started
*/
ProcessInstance startProcess(String processId,
Map<String, Object> parameters);
/**
* Signals the engine that an event has occurred. The type parameter defines
* which type of event and the event parameter can contain additional information
* related to the event. All process instances that are listening to this type
* of (external) event will be notified. For performance reasons, this type of event
* signaling should only be used if one process instance should be able to notify
* other process instances. For internal event within one process instance, use the
* signalEvent method that also include the processInstanceId of the process instance
* in question.
*
* @param type the type of event
* @param event the data associated with this event
*/
void
signalEvent(String type,
Object
event
);
/**
* Signals the process instance that an event has occurred. The type parameter defines
* which type of event and the event parameter can contain additional information
* related to the event. All node instances inside the given process instance that
* are listening to this type of (internal) event will be notified. Note that the event
* will only be processed inside the given process instance. All other process instances
* waiting for this type of event will not be notified.
*
* @param type the type of event
* @param event the data associated with this event
* @param processInstanceId the id of the process instance that should be signaled
*/
void
signalEvent(String type,
Object
event
,
long
processInstanceId);
/**
* Returns a collection of currently active process instances. Note that only process
* instances that are currently loaded and active inside the engine will be returned.
* When using persistence, it is likely not all running process instances will be loaded
* as their state will be stored persistently. It is recommended not to use this
* method to collect information about the state of your process instances but to use
* a history log for that purpose.
*
* @return a collection of process instances currently active in the session
*/
Collection<ProcessInstance> getProcessInstances();
/**
* Returns the process instance with the given id. Note that only active process instances
* will be returned. If a process instance has been completed already, this method will return
* null.
*
* @param id the id of the process instance
* @return the process instance with the given id or null if it cannot be found
*/
ProcessInstance getProcessInstance(
long
processInstanceId);
/**
* Aborts the process instance with the given id. If the process instance has been completed
* (or aborted), or the process instance cannot be found, this method will throw an
* IllegalArgumentException.
*
* @param id the id of the process instance
*/
void
abortProcessInstance(
long
processInstanceId);
/**
* Returns the WorkItemManager related to this session. This can be used to
* register new WorkItemHandlers or to complete (or abort) WorkItems.
*
* @return the WorkItemManager related to this session
*/
WorkItemManager getWorkItemManager();
|
3)Events
可以使用ProcessEventListener注册自己的监听器
public
interface
ProcessEventListener {
void
beforeProcessStarted( ProcessStartedEvent
event
);
void
afterProcessStarted( ProcessStartedEvent
event
);
void
beforeProcessCompleted( ProcessCompletedEvent
event
);
void
afterProcessCompleted( ProcessCompletedEvent
event
);
void
beforeNodeTriggered( ProcessNodeTriggeredEvent
event
);
void
afterNodeTriggered( ProcessNodeTriggeredEvent
event
);
void
beforeNodeLeft( ProcessNodeLeftEvent
event
);
void
afterNodeLeft( ProcessNodeLeftEvent
event
);
void
beforeVariableChanged(ProcessVariableChangedEvent
event
);
void
afterVariableChanged(ProcessVariableChangedEvent
event
);
}
|
默认支持下面的记录器实现:
1。 控制台记录器:此记录写入控制台的所有事件。
2。 文件记录器:此记录写入到一个文件中使用XML表示的所有事件。此日志文件可能被用来在IDE中生成一个基于树的可视化,在执行过程中发生的事件。
3。 线程文件记录器:因为文件记录器的事件写入到磁盘中,只有当关闭记录仪或记录器中的事件数量达到预定水平时,它不能被用来调试时,在运行过程。一个线程文件记录器的事件写入到一个文件后,在指定的时间间隔,使得它可以使用记录器以可视化的实时进展,而调试过程。
KnowledgeRuntimeLoggerFactory
可以添加logger到你的session中
KnowledgeRuntimeLogger logger =
KnowledgeRuntimeLoggerFactory.newFileLogger( ksession,
"test"
);
// add invocations to the process engine here,
// e.g. ksession.startProcess(processId);
...
logger.close();
|
业务流程创建
使用eclipse创建流程
可以在生成好的文件上定义业务流程
节点类型描述
BPMN 2.0规范定义了三种主要类型的节点
事件:它们用于模型中的特定事件的发生。这可能是一个开始事件(即用来指示的过程中开始),结束事件(定义过程结束,或该子流)和中间事件(指示的执行过程中可能出现的事件过程)。
活动:这些定义,需要在执行过程中执行不同的动作。存在不同类型的任务,对活动的类型取决于您尝试模型(如人工的任务,服务任务等)和actvities也可以嵌套(使用不同类型的子进程)。
网关:可以被用来定义多个路径的过程中。根据网关类型,这些可能表明并行执行,选择等
流程属性
一个BPMN2过程是不同类型的节点与使用连接流程图。这个过程本身暴露了以下属性:
事件
1)开始事件
进程的开始。一个过程应该有一个起始节点,没有传入的连接只有传出的连接
每当一个进程启动后,将开始执行此节点,并自动继续与这个启动事件的第一个节点,并依此类推。它包含以下属性:
2)结束事件
所有流程的结束,应该只有传入的连接没有传出的连接。它包含以下属性:
Terminate: 结束事件可以在整个过程中或终止路径。当一个流程实例被终止,这意味着它的状态设置为完成和所有其他节点可能仍然活跃在这个过程实例(并行路径)被取消。非终止结束事件只是这个路径(执行这个分支将在这里结束)结束,但仍然可以继续其他平行的路径。如果有流程实例内,没有更积极的的路径(例如,如果一个流程实例到达结束节点,但非终止流程实例内有没有更活跃的分支,将完成的过程实例,一个流程实例将自动完成反正)。终止结束事件的可视化的事件节点内使用一个完整的圆,非终止事件节点是空的。请注意,如果您使用一个子进程内的终止事件节点,你是终止流程实例的顶层,不只是子进程。
3)出错事件
错误处理事件,只能有传入事件没有传出事件,错误事件包含以下属性:
4)定时器事件
表示定时器后,可以触发一个特定的时间内一次或多次。计时器事件应该有一个传入的连接和一个外向连接。计时器延迟指定计时器之前应等待多久引发的第一次。当计时器事件的过程中达到的,它会启动相关的定时器。如果定时器节点被取消(例如,通过完成或中止封闭的过程实例),定时器就会被取消。
计时器事件包含以下属性:
5)信号事件
可用于信号事件,在执行过程中的内部或外部事件作出回应。信号事件有没有传入的连接和一个外向连接。它指定的事件类型,预计。每当检测到这种类型的事件,此事件节点相连的节点将被触发。它包含以下属性:
一个流程实例可以标志着一个特定的事件发生
ksession.signalEvent(eventType, data, processInstanceId)
|
这将触发所有在给定的进程实例(活动)信号,等待该事件类型的事件节点。与事件相关的数据可以通过使用数据参数。如果事件节点指定一个变量名,这个数据将被复制到该变量在事件发生时。
您还可以产生一个流程实例内的信号。可以使用一个脚本(脚本任务或进入或退出操作使用)
kcontext.getKnowledgeRuntime().signalEvent(
eventType, data, kcontext.getProcessInstance().getId());
|
6)活动
表示,应该在这个过程中执行的脚本。脚本任务应该有一个传入的连接和一个外向连接。指定应执行相关的操作,编码的行动(即Java或MVEL)使用的方言,和实际行动代码。此代码可以访问的任何变量和全局。还有一个预定义的变量kcontext引用ProcessContext对象,例如,它可以被用来访问当前流程实例或NodeInstance,并获得和设置变量,或获得ksession使用kcontext.getKnowledgeRuntime()。当一个脚本任务的过程中达成的,它会执行的动作,然后继续下一个节点。它包含以下属性:
请注意,您可以编写脚本节点内的任何有效的Java代码。这基本上允许你做这样一个脚本节点内部任何。但是也有一些注意事项:
7)服务任务
执行流程引擎之外的所有工作应派代表参加(以声明方式)使用服务任务。不同类型的服务是预定义的,例如,发送电子邮件,记录信息等,用户可以定义域特定的服务或工作项目,采用了独特的名称和定义的参数(输入)和相关的结果(输出)这种类型的工作。检查章特定于域的过程进行了详细的解释和例子说明如何定义和使用在你的流程的工作项目。当一个服务任务的过程中达成共识,相关的工作是执行。一个服务