jBPM与业务系统集成-通过定制Task Instance等方式实现
2008-11-17 17:15
435 查看
最近在jBPM的咨询/培训中,客户经常问到这么一个问题:jBoss jBPM很好,可是它只能为我们提供一个工作流引擎、一个业务流转的机制,但它不能替我们处理业务问题、管理业务数据,如何才能将已开发好的特定业务系统和jBPM流程引擎结合在一起运行呢?
把jBPM流程系统和客户业务系统整合在一起,归根到底其实就是将流程运行过程中的任务实例(task instance)和业务实例(business instance)关联起来,有两种方法:
1. 在业务系统中保存任务实例的引用,系统以业务为主导,能够从一笔业务办理中获取它在流程中的位置等上下文数据。
2. 在jBPM流程系统中保存业务实例的引用,系统以流程为主导,通过工作流的任务列表向用户提供业务任务,根据流程的任务实例的附加数据获取其绑定的具体业务数据。
一般情况下,我推荐方法1,因为它对工作流系统的没有侵入,只需要修改业务系统,在业务表中加入一个列保存task instance ID即可,这个步骤一般在业务系统设计阶段预先构架好。
但是,在业务系统已经定型等情况下,要将已有的业务系统加入工作流程管理中,而且不侵入之,方法1明显的就不合适了,那么如何实现方法2呢?还是有两种思路:
1. 将业务系统的引用作为流程/任务实例的变量(process/task instance varialbes)保存在jBPM系统中,那么通过流程/任务实例即可根据其绑定的业务引用变量查询业务实例数据。我们知道jBPM的变量系统是可以保存任何可序列化的对象的,所以我们甚至可以将整个业务实例的java object保存在jBPM工作流系统中(这样做可能比较疯狂,因为数据库存取二进制数据以及对象的序列/反序列化都是很影响效率的)。
2. 这是jBPM官方推荐的一种思路,修改jBPM TaskInstance数据库表!没错,就是修改jBPM的原始表结构、扩展它的源代码。请注意我用的是扩展,因为这不会修改任何jBPM的源码,而只是扩展之,这也是应用开源软件的一个好习惯:不要修改它的源代码,而是尽量利用它提供的机制去“扩展”出你需要的功能。
思路2的核心:首先在TaskInstance表中加一列,例如"BIZ_ID",用来保存业务系统的引用,诸如“订单ID”、“合同号”……
接着创造一个自定义的TaskInstance类,同时创建它的hbm描述文件(不要说你不懂hibernate哦,那神仙也没辙了),二者都需要继承jBPM原始的TaskInstance定义,例如:
public class CTaskInstance extends TaskInstance {
private static final long serialVersionUID = 1270139435455649329L;
protected String bizid;
public CTaskInstance() {
}
public CTaskInstance(String taskName) {
this.name = taskName;
}
public CTaskInstance(String taskName, String actorId) {
this.name = taskName;
this.actorId = actorId;
}
public String getBizid() {
return bizid;
}
public void setBizid(String bizid) {
this.bizid = bizid;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="false" default-access="field">
<subclass name="org.jbpm.customer.ctaskinstance.CTaskInstance"
discriminator-value="C"
extends="org.jbpm.taskmgmt.exe.TaskInstance">
<property name="bizid" column="BIZID_" />
</subclass>
</hibernate-mapping>
接下来你觉得该做什么呢?没错,将这个持久化类型的描述加入jBPM的hibernate.cfg.xml中,具体不表。
这时候,架构师们都会问:那如何让jBPM系统知道我们自定义的任务实例,并且在流程运行时使用的是它而非原始的任务实例呢?所以,我们需要替换jbpm.cfg.xml中的jbpm.task.instance.factory属性配置,将这个任务实例工厂替换为我们自己的实现,这下全明白了吧。
自定义任务实例工厂需要实现org.jbpm.taskmgmt.TaskInstanceFactory接口,例如:
public class CTaskInstanceFactoryImpl implements TaskInstanceFactory {
private static final long serialVersionUID = 1L;
public TaskInstance createTaskInstance(ExecutionContext executionContext) {
CTaskInstance ctaskin = new CTaskInstance();
ctaskin
.setBizid(new Date(System.currentTimeMillis())
+ "_U bizid here");
return ctaskin;
}
}
此时,有经验的看官还会有疑问:那么在哪将我们的业务数据ID插入自定义任务实例呢?还是两条路供选择:-)
1. 参见上面TaskInstanceFactory的实现:可以在createTaskInstance时,设置业务数据ID,提示:可以通过ExecutionContext对象从流程实例变量中取得业务数据ID,从而满足更加灵活的场景,当然你需要预先在流程实例中设置这个变量。
2. 可以通过编写/设置task controller来为每个customer task instance在start和end时设置业务数据ID,同样的,数据可以来自于流程实例预先绑定的变量。
那么,当我们的customer task instance在持久化提交时,业务数据ID即可随自定义任务实例对象存入数据库。
在官方的user guide(3.2.3版本)中有这样一段描述来简单的说明如何为业务扩展任务实例,供各位看官参考:
to create a subclass of TaskInstance. Then create a
org.jbpm.taskmgmt.TaskInstanceFactory implementation and
configure it by setting the configuration property jbpm.task.instance.factory
to the fully qualified class name in the jbpm.cfg.xml. If you use a subclass of
TaskInstance, also create a hibernate
mapping file for the subclass (using the hibernate
extends="org.jbpm.taskmgmt.exe.TaskInstance"). Then
add that mapping file to the list of mapping files in the
hibernate.cfg.xml
欢迎转载,请注明作者:胡奇
把jBPM流程系统和客户业务系统整合在一起,归根到底其实就是将流程运行过程中的任务实例(task instance)和业务实例(business instance)关联起来,有两种方法:
1. 在业务系统中保存任务实例的引用,系统以业务为主导,能够从一笔业务办理中获取它在流程中的位置等上下文数据。
2. 在jBPM流程系统中保存业务实例的引用,系统以流程为主导,通过工作流的任务列表向用户提供业务任务,根据流程的任务实例的附加数据获取其绑定的具体业务数据。
一般情况下,我推荐方法1,因为它对工作流系统的没有侵入,只需要修改业务系统,在业务表中加入一个列保存task instance ID即可,这个步骤一般在业务系统设计阶段预先构架好。
但是,在业务系统已经定型等情况下,要将已有的业务系统加入工作流程管理中,而且不侵入之,方法1明显的就不合适了,那么如何实现方法2呢?还是有两种思路:
1. 将业务系统的引用作为流程/任务实例的变量(process/task instance varialbes)保存在jBPM系统中,那么通过流程/任务实例即可根据其绑定的业务引用变量查询业务实例数据。我们知道jBPM的变量系统是可以保存任何可序列化的对象的,所以我们甚至可以将整个业务实例的java object保存在jBPM工作流系统中(这样做可能比较疯狂,因为数据库存取二进制数据以及对象的序列/反序列化都是很影响效率的)。
2. 这是jBPM官方推荐的一种思路,修改jBPM TaskInstance数据库表!没错,就是修改jBPM的原始表结构、扩展它的源代码。请注意我用的是扩展,因为这不会修改任何jBPM的源码,而只是扩展之,这也是应用开源软件的一个好习惯:不要修改它的源代码,而是尽量利用它提供的机制去“扩展”出你需要的功能。
思路2的核心:首先在TaskInstance表中加一列,例如"BIZ_ID",用来保存业务系统的引用,诸如“订单ID”、“合同号”……
接着创造一个自定义的TaskInstance类,同时创建它的hbm描述文件(不要说你不懂hibernate哦,那神仙也没辙了),二者都需要继承jBPM原始的TaskInstance定义,例如:
public class CTaskInstance extends TaskInstance {
private static final long serialVersionUID = 1270139435455649329L;
protected String bizid;
public CTaskInstance() {
}
public CTaskInstance(String taskName) {
this.name = taskName;
}
public CTaskInstance(String taskName, String actorId) {
this.name = taskName;
this.actorId = actorId;
}
public String getBizid() {
return bizid;
}
public void setBizid(String bizid) {
this.bizid = bizid;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="false" default-access="field">
<subclass name="org.jbpm.customer.ctaskinstance.CTaskInstance"
discriminator-value="C"
extends="org.jbpm.taskmgmt.exe.TaskInstance">
<property name="bizid" column="BIZID_" />
</subclass>
</hibernate-mapping>
接下来你觉得该做什么呢?没错,将这个持久化类型的描述加入jBPM的hibernate.cfg.xml中,具体不表。
这时候,架构师们都会问:那如何让jBPM系统知道我们自定义的任务实例,并且在流程运行时使用的是它而非原始的任务实例呢?所以,我们需要替换jbpm.cfg.xml中的jbpm.task.instance.factory属性配置,将这个任务实例工厂替换为我们自己的实现,这下全明白了吧。
自定义任务实例工厂需要实现org.jbpm.taskmgmt.TaskInstanceFactory接口,例如:
public class CTaskInstanceFactoryImpl implements TaskInstanceFactory {
private static final long serialVersionUID = 1L;
public TaskInstance createTaskInstance(ExecutionContext executionContext) {
CTaskInstance ctaskin = new CTaskInstance();
ctaskin
.setBizid(new Date(System.currentTimeMillis())
+ "_U bizid here");
return ctaskin;
}
}
此时,有经验的看官还会有疑问:那么在哪将我们的业务数据ID插入自定义任务实例呢?还是两条路供选择:-)
1. 参见上面TaskInstanceFactory的实现:可以在createTaskInstance时,设置业务数据ID,提示:可以通过ExecutionContext对象从流程实例变量中取得业务数据ID,从而满足更加灵活的场景,当然你需要预先在流程实例中设置这个变量。
2. 可以通过编写/设置task controller来为每个customer task instance在start和end时设置业务数据ID,同样的,数据可以来自于流程实例预先绑定的变量。
那么,当我们的customer task instance在持久化提交时,业务数据ID即可随自定义任务实例对象存入数据库。
在官方的user guide(3.2.3版本)中有这样一段描述来简单的说明如何为业务扩展任务实例,供各位看官参考:
12.10. Customizing task instances
Task instances can be customized. The easiest way to do this isto create a subclass of TaskInstance. Then create a
org.jbpm.taskmgmt.TaskInstanceFactory implementation and
configure it by setting the configuration property jbpm.task.instance.factory
to the fully qualified class name in the jbpm.cfg.xml. If you use a subclass of
TaskInstance, also create a hibernate
mapping file for the subclass (using the hibernate
extends="org.jbpm.taskmgmt.exe.TaskInstance"). Then
add that mapping file to the list of mapping files in the
hibernate.cfg.xml
欢迎转载,请注明作者:胡奇
相关文章推荐
- jBPM与业务系统集成-通过定制Task Instance等方式实现
- MOSS与业务系统的集成 之 自定义Membership实现Forms方式验证
- MOSS与业务系统的集成 之 自定义Membership实现Forms方式验证
- 不同语言,系统通过共享内存方式实现信息交互
- linux系统实现php通过pdo方式对sqlserver数据库的支持
- 前转方式实现秘书来话管理业务平台系统流程
- SpringBoot 集成 rabbitmq 简单实现通过队列进行,订单系统与库存系统,物流系统之间的信息交互
- 获取系统URL访问的前三名(通过Scala方式实现/通过Spark方式实现),Spark将URL访问日志进行分类并通过自定义Partitioner的方式将文件写入到不同分区上
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 几十套业务系统集中统一授权管理实现经验分享
- Activiti-5.18.0与springMvc项目集成和activiti-explorer单独部署Web项目并与业务数据库关联方法(AutoEE_V2实现方式)
- 通过portlet主动请求方式获得和portal通过LTPA方式集成的系统的登陆后某个页面的特定信息(portal SSO)
- 通过银行转账业务体会JAVA与存储过程不同实现方式
- 通用权限管理系统多语言开发接口 ,多业务子系统集成实现过程
- 请教.Net平台大型业务系统中“日志记录” 的较好解决办法,类似Java下用AOP方式实现的最好
- SQL学习笔记[5] - 通过分隔符解析方式实现向SQL存储过程传递数组参数
- 通过模仿AsyncTask的封装方式,实现一个后台预读数据的线程,(使用AsyncTask有导致应用FC的风险)
- vc6.0读取系统时间并与自己通过其他方式获取的时间比较
- WebLogic 通过数据库的方式实现Session共享的配置
- 基于WebForm+EasyUI的业务管理系统形成之旅 -- 首页快捷方式(Ⅲ)