`
royzhou1985
  • 浏览: 249655 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Jbpm基础知识

    博客分类:
  • JBPM
阅读更多
1、重要的对象
JbpmConfiguration
主要用来读取配置文件,并且提供流程运行过程中所需要的各种服务对象
在jbpm源文件目录下org.jbpm包下面有一个default.jbpm.cfg.xml文件,它是jbpm默认采用的配置文件
<jbpm-configuration>
  <!-- 
    This configuration is used when there is no jbpm.cfg.xml file found in the 
    root of the classpath.  It is a very basic configuration without persistence
    and message services.  Only the authorization service installed.
    You can parse and create processes, but when you try to use one of the 
    unavailable services, you'll get an exception.
  -->
  <!--主要用来配置各种服务类:持久化、消息、日志、日历等等-->
  <jbpm-context>
    <service name="persistence" factory="org.jbpm.persistence.db.DbPersistenceServiceFactory" />
    <service name="tx" factory="org.jbpm.tx.TxServiceFactory" />
    <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" />
    <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" />
    <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" />
    <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" />
  </jbpm-context>

  <!-- configuration property used by persistence service impl org.jbpm.persistence.db.DbPersistenceServiceFactory -->
<!--主要用来配置Hibernate配置文件的位置-->
  <string name="resource.hibernate.cfg.xml" value="hibernate.cfg.xml" />

  <!-- configuration resource files pointing to default configuration files in jbpm-{version}.jar -->
<!--主要用来配置Jbpm的其他一些县官配置文件的位置-->
  <string name="resource.business.calendar" value="org/jbpm/calendar/jbpm.business.calendar.properties" />
  <string name="resource.default.modules" value="org/jbpm/graph/def/jbpm.default.modules.properties" />
  <string name="resource.converter" value="org/jbpm/db/hibernate/jbpm.converter.properties" />
  <string name="resource.action.types" value="org/jbpm/graph/action/action.types.xml" />
  <string name="resource.node.types" value="org/jbpm/graph/node/node.types.xml" />
  <string name="resource.parsers" value="org/jbpm/jpdl/par/jbpm.parsers.xml" />
  <string name="resource.varmapping" value="org/jbpm/context/exe/jbpm.varmapping.xml" />
  <string name="resource.mail.templates" value="jbpm.mail.templates.xml" />

  <int    name="jbpm.byte.block.size" value="1024" singleton="true" />
  <bean   name="jbpm.task.instance.factory" class="org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl" singleton="true" />
  <bean   name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver" singleton="true" />
  <string name="jbpm.mail.smtp.host" value="localhost" />
  <bean   name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver" singleton="true" />
  <string name="jbpm.mail.from.address" value="jbpm@noreply" />
<!—任务调度--> 
  <bean name="jbpm.job.executor" class="org.jbpm.job.executor.JobExecutor">
    <field name="jbpmConfiguration"><ref bean="jbpmConfiguration" /></field>
    <field name="name"><string value="JbpmJobExecutor" /></field>
    <field name="nbrOfThreads"><int value="1" /></field>
    <field name="idleInterval"><int value="5000" /></field>
    <field name="maxIdleInterval"><int value="3600000" /></field> <!-- 1 hour -->
    <field name="historyMaxSize"><int value="20" /></field>
    <field name="maxLockTime"><int value="600000" /></field> <!-- 10 minutes -->
    <field name="lockMonitorInterval"><int value="60000" /></field> <!-- 1 minute -->
    <field name="lockBufferTime"><int value="5000" /></field> <!-- 5 seconds -->
  </bean>
</jbpm-configuration>


如果需要修改默认配置,我们只需要在我们的classpath下面新建一个jbpm.cfg.xml文件添加我们要修改的内容

JbpmConfiguration是单例的,通过JbpmConfiguration的静态方法getInstance()获得
JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
JbpmConfiguration最常用的一个方法就是用来创建一个JbpmContext对象
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
其他常用方法:
Public void createSchema() 创建jbpm数据库
Public void dropSchema()  删除jbpm数据库
(具体方法可以查阅Jbpm API)

JbpmContext
对象主要用来操作流程,可以新建流程、查找任务实例、获取某个人的代办任务等等。通过JbpmContext的持久化会产生事务,在jbpmContext调用close()方法的时候会提交事务。
一般的处理代码如下:
JbpmContext jbpmContext = null;
try{
jbpmConfiguration.createJbpmContext();
//相关操作
} catch(Exception e) {
	e.printStackTrace();
} finally {
	jbpmContext.close(); //提交事务,持久化数据到数据库中
}

如果是在web中使用Jbpm为我们提供了一个JbpmContextFilter类,位于org.jbpm.web包下面,其中主要的源码如下:
JbpmContext jbpmContext = getJbpmConfiguration().createJbpmContext(jbpmContextName);
    try {
      if (isAuthenticationEnabled) {
        jbpmContext.setActorId(actorId);
      }
      filterChain.doFilter(servletRequest, servletResponse);
    } finally {
      jbpmContext.close();
}


可以看出,使用过滤器,JbpmContext对象创建完成之后会放置到线程局部变量(ThreadLocale)中,所以我们可以通过这样一种方式获取:
JbpmConfiguration.getCurrentJbpmContext()方法获取。

比较两种获取JbpmContext的方式:在filter中配置可以省去close()的步骤,可以避免忘记关闭jbpmContext,但是每次请求都会创建一个对象。 具体使用哪种需要使用者权衡。

jbpmContext的主要方法有:
发布流程:public void deployProcessDefinition(ProcessDefinition pd);
创建新的流程实例:public ProcessInstance newProcessInstance(String processName);
加载流程实例:public TaskInstance getTaskInstance(long taskInstanceId);
  Public TsakInstance loadTaskInstance(long taskInstanceId):
加载流程实例:public ProcessInstance loadProcessInstance(long processInstanceId);
代办任务列表:public List getTaskList(String actorId);
(具体方法可以查阅Jbpm API)

ProcessDefinition 和 ProcessInstance
ProcessDefinition是流程定义对象,对应的数据表是jbpm_processdefinition ,流程定义有版本控制,允许同名的流程定义共存。当新版本发布后,新流程实例使用新版本启动,老的流程实例使用老的流程定义启动。 获取最新版本的流程定义对象可以通过下面代码实现:
ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition(String processName)
获取所有最新版本的流程定义对象可以用下面方法:
List processDefinitions = jbpmContext.getGraphSession().findLatestProcessDefinitions()
当然也可以获取特定版本的流程定义对象,通过版本来实现:
ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition(String processName,String version)

ProcessDefinition与ProcessInstance是一对多的关系。

ProcessDefinition常用方法:
Public static void parseXmlInputStream(InputStream is) 解析流程定义
Public statci void parseXmlResource(String xmlResource) 解析流程定义
Public static void parZipInputStream(ZipInputStream zis) 解析流程定义
Public ProcessInstance createProcessInstance() : 不带参数
Public ProcessInstance createProcessInstance(Map variables) :流程变量初始化
(其他方法查阅API)

ProcessInstance常用方法:
Public ContextInstance getContextInstance()     获取流程实例对应的流程上下文对象
Public ProcessDefinition getProcessDefinition()  获取流程定义对象
Public Token getRootToken()  获取流程实例的Token对象
Public void signal() 驱动流程往下流转
Public TaskMgmtInstance getTaskMgmtInstance()获取流程实例对应的任务实例管理对象
Public void suspend() 暂停
Public void resume() 继续 
注意,暂停状态下Token的signal()方法不可执行,必须先执行resume()方法
Token
当我们新建一个流程实例时,同时创建了一个根令牌Token,通过processInstance的getRootToken()方法可以获取根令牌,其指向start节点。当我们对token发送一个信令,即token.signal()方法执行时,实际上就是驱使流程流向下一个节点。Token可以拥有子Token,如fork节点会产生子Token,也就是并行。流程遇到fork节点会产生子Token,当所有子Token执行完之后又回到父Token上,继续往下执行。
Token的主要方法:
Public void signal()    驱动流程往下流转
Public Node getNode()     获取Token所在节点对象
Public ProcessInstance getProcessInstance()  获取token所属流程实例
(其他方法查阅API)

ContextInstance
流程上下文对象,主要是用来存储流程变量的。它是随着流程实例的产生而产生的。通过ContextInstance我们实现流程变量的读写和删除。
Public void setVariable(String name,Object value)  设置流程变量
Public Object getVariable(String name)   获取流程变量
Public void deleteVariable(String name);   删除流程变量
流程变量有作用域,可以在参数里面通过指定Token来区分是根Token还是子Token的,类似全局变量和局部变量。如下:
Public void setVariable(String name,Object value,Token token)   设置流程变量
Public Object getVariable(String name,Token token)   获取流程变量
Public void deleteVariable(String name,Token token);       删除流程变量

注意,流程变量允许覆盖,但是覆盖的时候Object的类型必须相同

Jbpm还提供了一种瞬时变量,其生命周期是流程实例离开一个节点并且进去下一个节点的过程,并且不会持久化到数据库中。瞬时变量的使用如下:
写入瞬时变量:public void setTransientVariable(String name,Object value)
读取瞬时变量:public Object getTransientVariable(String name)
JBPM流程变量支持的类型包括一般的数据类型,此外还支持java.io.Serializable类型,我们可以编写实现这个接口的类存储到流程变量中。

Action
是指一系列实现ActionHandler的类。可以定义在流程相关节点或者相关节点的事件当中。主要的处理是通过实现方法execute来实现:
比如在一个Node节点下设置了node-enter事件,我们可以定义Action类处理,利用之前的helloworld例子,类似这样:
	<state name="state1">
		<event type="node-enter">
			<action class="com.royzhou.action.NodeEnterAction"></action>
		</event>
		<transition to="end-state1"></transition>
</state>


这样我们可以在Action类中简单打印一个提示:
package com.royzhou.action;

import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;

public class NodeEnterAction implements ActionHandler {
	public void execute(ExecutionContext executionContext) throws Exception {
		System.out.println("node enter……………………");
	}
}	

重新发布之后运行之前的例子发现在流程进入state1节点的时候后台打印出了"node enter……………………",说明Action触发了。

Transition
又成为路由,是用来处理Token流转的。Token调用signal的时候可以指定Tansition,如果定义了多个Transition,并且没有指定使用那个Transition,则默认取第一个Transition(数据库中查询出来的第一个Transition)。注意Transition的源不能是End节点,目标不能是Start节点,且名称不能重复。
有时我们可以通过动态创建Transition来简化我们的流程图,动态创建Transition的方法如下:
public Transition createTransition(Node fromNode,Node toNode) throws Exception {
	String transitionName = “tempLeavingTransition”;
	Transition transition = new Transition(transitionName);
	transition.setTo(toNode);
	fromNode.addLeavingTransition(transition);
	return transition;
}

BeanShell脚本
BeanShell是Jbpm中Jpdl使用的一种弱类型脚本。官方网站是:http://www.beanshell.org。
Jpdl中,beanshell脚本可以直接获取到Token,ExecutionContext,Node对象,同时可以直接访问流程变量,利用beanshell脚本有时候可以简化我们的代码,例如在decision节点上我们可以直接在流程定义文件中编写脚本来判断流程走向,省去了编写实现decisionhandler接口的类。
2、使用jbpm数据库发布流程
数据库创建的两种方式:(个人比较喜欢第一种方式,呵呵。)
1、 通过JbpmConfiguration对象的createSchema()方法,必须先配置好hibernate配置文件
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jbpm</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">1234</property>
    <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

2、 直接使用数据库脚本(路径:jbpm-jpdl-3.2.3\db)

发布流程:(流程的发布需要三个文件)
processdefinition.xml: 主要定义文件  gpd.xml:坐标文件 processimage.jpg:流程图片

发布的时候必须使用zip压缩将三个文件不带目录压缩。流程发布的实例代码如下:
public static void deploy() throws FileNotFoundException {
		JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		try {
			FileInputStream fis = new FileInputStream("jbpm-test/src/main/jpdl/helloworld.zip ");
			ZipInputStream zis = new ZipInputStream(fis);
			ProcessDefinition processDefinition = ProcessDefinition.parseParZipInputStream(zis);
			jbpmContext.deployProcessDefinition(processDefinition);
			fis.close();
			zis.close();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			jbpmContext.close();
		}
	}

如果发布成功,查看数据库发现数据表:jbpm_processdefinition多了一条记录,就是你刚刚发布的流程,同时会将图片及坐标文件存储到数据表jbpm_bytearray和jbpm_byteblock中。
当然你也可以单独使用processdefinition.xml发布流程。这样发布的流程将看不到流程的流转图。。 (关于流程图的内容稍后再介绍)

下面我们编写流程测试类:

package com.royzhou.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.zip.ZipInputStream;

import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;

public class HelloWorldDB {
	public static void deploy() throws FileNotFoundException {
		JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		try {
			FileInputStream fis = new FileInputStream("F:/workspace/jbpm-test/src/main/jpdl/helloworld/helloworld.zip ");
			ZipInputStream zis = new ZipInputStream(fis);
			ProcessDefinition processDefinition = ProcessDefinition.parseParZipInputStream(zis);
			jbpmContext.deployProcessDefinition(processDefinition);
			fis.close();
			zis.close();
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			jbpmContext.close();
		}
	}
	
	public static void main(String[] args) throws FileNotFoundException {
		HelloWorldDB.deploy();
		JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
		JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
		//获取最新版本的流程定义对象
		ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition("helloworld");
		ProcessInstance processInstance = new ProcessInstance(processDefinition);
		//得到流程令牌
		Token token = processInstance.getRootToken();
		
		//打印流程当前所处节点
		System.out.println("1:流程现在所处节点:" + token.getNode().getName());
		
		//触发流程流转到下一个节点Node
		token.signal();
		
		/**
		 * 注意因为Node节点没有设置Action
		 * 所以流程会自动流转到下一个节点
		 * 也就是State1
		 */
		System.out.println("2:流程现在所处节点:" + token.getNode().getName());
		
		//触发流程流转到下一个节点End
		token.signal();
		System.out.println("3:流程现在所处节点:" + token.getNode().getName());
		System.out.println("流程状态是否结束:" + token.getProcessInstance().hasEnded());
		jbpmContext.close();
	}
}

执行结果如下:
1:流程现在所处节点:start-state1
2:流程现在所处节点:state1
3:流程现在所处节点:end-state1
流程状态是否结束:true

同时查看数据库表:jbpm_processdefinition多了一条记录, 就是我们刚刚发不的流程定义,jbpm_processinstance 发现多了一条记录,就是我们刚刚走完的一个流程。

到这里我们就把Jbpm中常用的对象介绍了一下,实际开发中建议多查阅API。。。。。

分享到:
评论

相关推荐

    JBPM4.3工作流基础知识学习

    JBPM4工作流基础知识学习,自己总结的,东西比较基础。 有代码和样例

    传智播客jbpm教程

    传智播客jbpm教程,分四部由浅入深的讲解jbpm的基础知识,到应用开发,对于初学者和想要提高的人有很大帮助

    jbpm3.1中文文档

    jbpm的一些基础知识,工作流是个很好用的东西哦~

    jBPM4学习总结

    jBPM学习总结,涵盖jBPM4的各个基础知识点,及实例解析。

    JBPM工作流介绍ppt

    jbpm 工作流的介绍。基础知识,一些参考

    JBPM5 用户指南

    第五章 核心引擎:基础 21 5.1 创建一个流程 21 5.1.1 Eclipse BPMN2.0图形编辑器插件 22 5.1.2 使用XML定义流程 22 5.1.3使用流程API定义流程 24 5.2 不同流程构造的细节概述 25 5.3 流程属性的细节 26 5.4 事件...

    JBPM5权威指南

    第五章 核心引擎:基础 21 5.1 创建一个流程 21 5.1.1 Eclipse BPMN2.0图形编辑器插件 22 5.1.2 使用XML定义流程 22 5.1.3使用流程API定义流程 24 5.2 不同流程构造的细节概述 25 5.3 流程属性的细节 26 5.4 事件...

    JBPM开发指南word版本

    JBPM开发指南.word,基础知识点入门。

    jBPM4.1中文用户手册

    建议读者先自行上网了解jbpm的基本概念以及流程的定义等基础知识,在理解了jbpm的基础之上学习这份文档会有更大的收获!

    jbpm工作流引擎介绍.ppt

    jbpm 工作流的介绍。基础知识,一些参考

    jBPM5 用户指南-中文

    第五章 核心引擎:基础 27 5.1 创建一个流程 27 5.1.1 Eclipse BPMN2.0图形编辑器插件 28 5.1.2 使用XML定义流程 28 5.1.3使用流程API定义流程 30 5.2 不同流程构造的细节概述 31 5.3 流程属性的细节 32 5.4 事件...

    JBPM5用户指南-PDF电子书-官方文档翻译

    jBPM5官方文档,jBPM5 User Guide的中文翻译版。正宗PDF格式电子书。 目录: 第一章 概述 第二章 获得开始 第三章 安装 第四章 核心引擎的API 第五章 核心引擎:基础 第六章 BPMN2.0核心引擎 第七章 核心引擎:持久...

    基于LigerUI+JBPM5自定义表单+Node.js的J2EE大型金融项目《财务预算系统》开发全程实录.rar

    基于LigerUI+JBPM5自定义表单+Node.js的J2EE大型金融项目《财务预算系统》开发全程实录——课程分为三季: 第一季:基础篇,主要内容包括:基础设置,主要是对整个框架的搭建,对流程的控制,对所用到的技术进行...

    javaeye热点阅读

    这是JavaEye论坛热点推荐_-_2009年2月_-_总第9期,个人认为对于JAVA学习的程序员了解当前的一些知识及行业动态非常有帮助。 1.0 Java 1.1 分享开源表达式解析器IK-Expression2.0 1.2 jbpm3与jbpm4实现对比 1.3 Java...

    JBOSS ESB程序员指南

    2.3. 必要知识 5 2.4. 本指南的组织结构 5 2.5. 关于本文档的协定 5 2.6. 附件 6 2.7. 我们的联系方式 6 3. 第一章 面向服务的体系结构 7 3.1. 概述 7 3.2. 什么是SOA 8 3.3. SOA的基础 10 3.4. SOA的优点 10 3.5. ...

    我国GIS软件的发展现状

    通过实际构造GIS应用系统,解决了应用领域知识的提炼、综合以及与 GIS技术的结合问题,提高了大型GIS应用工程的开发管理水平,积累了较为丰富的GIS应用经验。  近年来,GIS已经成为不少部门和单位日常工作的业务...

    Activiti6.0教程例子下载

    由于本人之前没有工作流及JBPM的相关基础,刚开始学习Activiti的时候可以说是无比痛苦的,根本不知道从何下手,这里也建议大家先进行工作流及BPMN2.0规范的学习,有了一定的基础后,再着手学习Activiti。 1.3.2. ...

    技术实现大型J2EE金融行业财务预算系统(第二季)38课

    本课程系讲师在实际工作中的一真实项目,除简化了部分业务逻辑外,基础架构及核心模块超均来自企业项目。本课程为第二季。 本季的内容主要包括:预算编制及预算调整,主要将第一部分所用到的技术知识进行深化,以及...

    技术实现大型J2EE金融行业财务预算系统(第二季)49讲

    本课程系讲师在实际工作中的一真实项目,除简化了部分业务逻辑外,基础架构及核心模块超均来自企业项目。本课程为第二季。 本季的内容主要包括:预算编制及预算调整,主要将第一部分所用到的技术知识进行深化,以及...

    技术实现大型J2EE金融行业财务预算系统(第二季)-20课

    本课程系讲师在实际工作中的一真实项目,除简化了部分业务逻辑外,基础架构及核心模块超均来自企业项目。本课程为第二季。 本季的内容主要包括:预算编制及预算调整,主要将第一部分所用到的技术知识进行深化,以及...

Global site tag (gtag.js) - Google Analytics