- 浏览: 2447627 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (574)
- Book (62)
- Architecture (6)
- Java (39)
- Taobao (41)
- Distributed (4)
- Life (72)
- Database (7)
- Spring (16)
- Photography (15)
- Bicycle (41)
- Test (20)
- jBPM (8)
- Business (12)
- Movie (3)
- Ajax (15)
- Code (7)
- Eclipse (96)
- VIM (2)
- Music (6)
- Groovy (10)
- AutoHotKey (3)
- Dorado (10)
- Maven (7)
- Scrum (5)
- English (20)
- Financial (12)
- OSGi (3)
- Other (4)
- Tool (6)
- Browser (1)
- PPT (1)
- Project Management (4)
- Agile (6)
- Nosql (1)
- Search engine (6)
- Shell (2)
- Open Source (4)
- Storm (10)
- Guava (3)
- Baby (1)
- netty (1)
- Algorithm (1)
- Linux (1)
- Python (2)
最新评论
-
roy2011a:
https://github.com/ebottabi/sto ...
storm的序列化问题及与spring的结合方式 -
roy2011a:
能抗能打 写道哥们儿,你好!能共享下那个storm与sprin ...
storm的序列化问题及与spring的结合方式 -
Alick1:
兄弟,你之前是不是在深圳的正阳公司呆过啊?
storm的ack和fail -
liuleixwd:
先点个赞,写的非常好!有个问题请教下,如果我再bolt里不用e ...
storm的ack和fail -
yao-dd:
solr的facet查询
★使用jbpm提供的eclipse plugin在画流程图的时候, 一般的步骤是先画各种节点(我画流程图的顺序是这样的:start node, end node, task node, common node....),然后保存关闭,再打开继续添加transition,因为插件设计器有一个缺点就是第一次就画好transition之后再打开会"惨不忍睹", 各种node会摆放的乱七八糟.
★一般我们认为未命名的那个transtion是默认要执行的transtion,其实不是这样的,通过看源代码:
我们可以看出,实际上第一个transtion才是默认的transition,所以在画流程图的时候要注意这一点,为了让未命名的transtion作为默认的transtion,必须将其放在第一个.
★jbpm数据表结构分析
不管是task变量还是process变量,都保存在jbpm_variableinstance表中,从该表中我们可以看出, 只能存取byte, date, double, long和string这几种类型的变量,所以如果你设置的变量类型为int类型,那么实际上取出来的是long类型的,所以在使用getVariable()方法要取得int类型变量,注意要造型为long.
★不管是task变量还是process变量, 如果要取变量值, 有两种方式, 一种是通过中间表jbpm_tokenvariablemap和jbpm_moduleinstance, jbpm使用hibernate就是通过该方式来取得的, 另一种是通过jbpm_variableinstance表的processinstantce_字段来取得, 一般如果我们手工来获取的话,可以通过该字段来取得.
★ContextInstance实例对应的表是jbpm_moduleinstance,ProcessInstance实例对应的表是jbpm_processintance
★进入子流程之前的事件是subprocess-created而不时node-enter
★token类是一个非常底层的东东,在实际的工作流中很少用到,而用到最多的就是task node以及附加在各个节点上的action handler, 因为只有task node才是人能参与流程的地方, 而jBPM工作流的主要任务就是通过人的操作来让流程运行, 如果在很多地方使用token,那说明你的流程不是人在操作,而是机器在操作.所以大部分我看到的使用token的地方都是在测试中,因为需要通过代码来让流程自动运行.
★state node会将当前的流程挂起,这跟org.jbpm.graph.node.State类有关:
因为它的execute()方法为空, 而其他的节点的execute方法中都会调用leave()方法继续流程的执行,跑到下一个节点,也别指望在state node中通过ProcessInstance.signal()方法来启动流程,因为没有地方提供你放该执行代码,即使通过在event的actionhandler中来让流程继续执行也不行,因为在执行execute方法之前有一个流程锁定的动作,而在execute方法执行之后则有一个解锁的处理,而位于action中execute方法中的signal方法也会检查当前节点是否锁定,因为在执行execute方法之前已经锁定所以会抛出node被锁定的异常.而要让流程继续执行需要在流程之外通过调用ProcessInstance.signal()方法让流程继续执行.
★一般流程图的画法, 一般按照流程的顺序遵循从上到下,从左到右的原则[img]http://macrochen.iteye.com/upload/picture/pic/14941/61a7b9f3-29e3-322a-9d76-9b927bec236e.jpg [/img]
★申请界面可能千差万别,但是审核页面都基本类似:审核内容,审核历史,审核意见, 所以我做成了通用的页面[img]http://macrochen.iteye.com/upload/picture/pic/14945/b3966fb3-2a30-331e-b40a-4fec6cdd9316.png [/img]
★为了将业务表单数据挂到jBPM流程引擎上,一般需要使用一个全局的流程实例变量(我一般采用FORM_ID)将指定的业务表单记录主键保存,这样在流程中的不同节点就可以取得所需要的业务数据,并交给不同的操作对象(Actor)进行处理.
★为了使用指定的页面来处理每个流程任务节点,需要将页面的url保存为任务节点变量, 这样就将jsp页面跟jBPM流程的任务节点联系起来了.而这个工作是放在AssignmentHandler中来处理的.在本人的项目中这是一个通用的做法,所以写了一个AssignmentHandler抽象类:
★以下是本人总结的一些公共的,方便的jBPM静态方法,在整个项目中通用:
目前在昆明做项目
是的,是dorado+jbpm的项目
目前我还没有碰到特别需要注意的地方
Spring有个jBPM的module,挺有用的,可以用一下。特别是里面的JbpmTemplate。
从文章里可以看出一点,你们好像不太看文档,哈哈。很多问题都在文档里有写。
这个我当然是知道的,只是开始一直没搞懂state node怎么用,后来才明白过来, spring的jbpm module没看过,有时间看看
★一般我们认为未命名的那个transtion是默认要执行的transtion,其实不是这样的,通过看源代码:
public Transition getDefaultLeavingTransition() { Transition defaultTransition = null; if ( (leavingTransitions!=null) && (leavingTransitions.size()>0) ) { defaultTransition = (Transition) leavingTransitions.get(O); } else if ( superState!=null ){ defaultTransition = superState.getDefaultLeavingTransition(); } return defaultTransition; }
我们可以看出,实际上第一个transtion才是默认的transition,所以在画流程图的时候要注意这一点,为了让未命名的transtion作为默认的transtion,必须将其放在第一个.
★jbpm数据表结构分析
不管是task变量还是process变量,都保存在jbpm_variableinstance表中,从该表中我们可以看出, 只能存取byte, date, double, long和string这几种类型的变量,所以如果你设置的变量类型为int类型,那么实际上取出来的是long类型的,所以在使用getVariable()方法要取得int类型变量,注意要造型为long.
★不管是task变量还是process变量, 如果要取变量值, 有两种方式, 一种是通过中间表jbpm_tokenvariablemap和jbpm_moduleinstance, jbpm使用hibernate就是通过该方式来取得的, 另一种是通过jbpm_variableinstance表的processinstantce_字段来取得, 一般如果我们手工来获取的话,可以通过该字段来取得.
★ContextInstance实例对应的表是jbpm_moduleinstance,ProcessInstance实例对应的表是jbpm_processintance
★进入子流程之前的事件是subprocess-created而不时node-enter
★token类是一个非常底层的东东,在实际的工作流中很少用到,而用到最多的就是task node以及附加在各个节点上的action handler, 因为只有task node才是人能参与流程的地方, 而jBPM工作流的主要任务就是通过人的操作来让流程运行, 如果在很多地方使用token,那说明你的流程不是人在操作,而是机器在操作.所以大部分我看到的使用token的地方都是在测试中,因为需要通过代码来让流程自动运行.
★state node会将当前的流程挂起,这跟org.jbpm.graph.node.State类有关:
public class State extends Node { private static final long serialVersionUID = 1L; public State() { this(null); } public State(String name) { super( name ); } public void execute(ExecutionContext executionContext) { } }
因为它的execute()方法为空, 而其他的节点的execute方法中都会调用leave()方法继续流程的执行,跑到下一个节点,也别指望在state node中通过ProcessInstance.signal()方法来启动流程,因为没有地方提供你放该执行代码,即使通过在event的actionhandler中来让流程继续执行也不行,因为在执行execute方法之前有一个流程锁定的动作,而在execute方法执行之后则有一个解锁的处理,而位于action中execute方法中的signal方法也会检查当前节点是否锁定,因为在执行execute方法之前已经锁定所以会抛出node被锁定的异常.而要让流程继续执行需要在流程之外通过调用ProcessInstance.signal()方法让流程继续执行.
★一般流程图的画法, 一般按照流程的顺序遵循从上到下,从左到右的原则[img]http://macrochen.iteye.com/upload/picture/pic/14941/61a7b9f3-29e3-322a-9d76-9b927bec236e.jpg [/img]
★申请界面可能千差万别,但是审核页面都基本类似:审核内容,审核历史,审核意见, 所以我做成了通用的页面[img]http://macrochen.iteye.com/upload/picture/pic/14945/b3966fb3-2a30-331e-b40a-4fec6cdd9316.png [/img]
★为了将业务表单数据挂到jBPM流程引擎上,一般需要使用一个全局的流程实例变量(我一般采用FORM_ID)将指定的业务表单记录主键保存,这样在流程中的不同节点就可以取得所需要的业务数据,并交给不同的操作对象(Actor)进行处理.
★为了使用指定的页面来处理每个流程任务节点,需要将页面的url保存为任务节点变量, 这样就将jsp页面跟jBPM流程的任务节点联系起来了.而这个工作是放在AssignmentHandler中来处理的.在本人的项目中这是一个通用的做法,所以写了一个AssignmentHandler抽象类:
/** * 审核任务节点对应的分配处理handler 主要设置处理当前审核任务的actor和审核操作页面, 默认的审核页面不能对审核内容进行编辑 * * @author Macro Chen * @since Apr 18, 2008 */ public abstract class BaseAssignmentHandler implements AssignmentHandler { public void assign(Assignable assignable, ExecutionContext ctx) throws Exception { addContextInstanceVariables(ctx.getContextInstance()); String employeeId = getActorId(assignable, ctx); assignable.setActorId(employeeId); addTaskInstanceVariables(assignable, ctx); } /** * 添加task instance变量 * * @param assignable * @param ctx */ protected void addTaskInstanceVariables(Assignable assignable, ExecutionContext ctx) { TaskInstance ti = (TaskInstance) assignable; String url = getOperationUrl(assignable, ctx); url += (url.indexOf("?") != -1 ? "&" : "?") + "taskId=" + ti.getId(); ti.setVariable(JbpmConstants.TIV_OPERATION_URL, url); } /** * 根据业务需要添加其他的流程变量 * * @param ci */ protected void addContextInstanceVariables(ContextInstance ci) { } /** * 执行任务操作的页面 默认情况下使用通用的审核页面(不可对审核内容进行修改), 子类可以根据需要开发自己的审核页面(如可对审核内容进行修改) * * @return */ protected String getOperationUrl(Assignable assignable, ExecutionContext ctx) { return "/workflow/common/common_audit.jsp"; } /** * 设置当前任务节点的执行者 * * @param assignable * @param ctx * @return * @throws Exception */ protected abstract String getActorId(Assignable assignable, ExecutionContext ctx) throws Exception; }
★以下是本人总结的一些公共的,方便的jBPM静态方法,在整个项目中通用:
/** * @author Macro Chen * @since Apr 8, 2008 */ public class JbpmUtils { public static Long getLongVariableOfProcess(IJbpmProvider provider, String name) { ContextInstance ci = provider.getContextInstance(); if (ci == null) { return (long)0; } return (Long)ci.getVariable(name); } public static JbpmContext getJbpmContext() { JbpmConfiguration config = JbpmConfiguration.getInstance(); return config.getCurrentJbpmContext(); } /** * 新建一个pi * * @param name * @return */ public static ProcessInstance newProcessInstance(String name) { ProcessDefinition pd = getJbpmContext().getGraphSession() .findLatestProcessDefinition(name); return new ProcessInstance(pd); } /** * 根据taskId取得pi * * @param taskId * @return */ public static ProcessInstance getProcessInstanceByTaskId(String taskId) { TaskInstance ti = getTaskInstance(taskId); return ti.getTaskMgmtInstance().getProcessInstance(); } public static ProcessInstance getProcessInstanceByTaskId(Long taskId) { TaskInstance ti = getTaskInstance(taskId); return ti.getTaskMgmtInstance().getProcessInstance(); } public static ContextInstance getContextInstance(String name) { return newProcessInstance(name).getContextInstance(); } public static ContextInstance getContextInstanceByTaskId(String taskId) { TaskInstance ti = getTaskInstance(taskId); if (ti == null) return null; return ti.getTaskMgmtInstance().getProcessInstance() .getContextInstance(); } public static ContextInstance getContextInstanceByTaskId(Long taskId) { TaskInstance ti = getTaskInstance(taskId); if (ti == null) return null; return ti.getTaskMgmtInstance().getProcessInstance() .getContextInstance(); } public static TaskInstance createStartTaskInstance(ProcessInstance pi) { return pi.getTaskMgmtInstance().createStartTaskInstance(); } public static Session getSession() { return getJbpmContext().getSessionFactory().openSession(); } public static List getQueryList(String hql) { return getSession().createQuery(hql).list(); } public static TaskMgmtSession getTaskMgmt() { return getJbpmContext().getTaskMgmtSession(); } public static TaskInstance loadTaskInstance(long taskId) { return getTaskMgmt().loadTaskInstance(taskId); } public static TaskInstance getTaskInstance(String taskId) { if (StringUtils.isEmpty(taskId)) return null; return getJbpmContext().getTaskInstance(Long.parseLong(taskId)); } public static TaskInstance getTaskInstance(long taskId) { return getJbpmContext().getTaskInstance(taskId); } public static List<TaskInstance> findTaskInstances(String actorId) { return getTaskMgmt().findTaskInstances(actorId); } public static List<TaskInstance> findPooledTaskInstances(String actorId) { return getTaskMgmt().findPooledTaskInstances(actorId); } public static void saveTaskInstance(TaskInstance ti) { getJbpmContext().save(ti); } public static String getTaskId() { return DoradoUtils.getRequestParameter(JbpmConstants.TASK_ID); } }
评论
12 楼
jslzl
2009-09-29
请教:
刚刚接触JBPM的东东,对于审核历史的功能,我应该有哪些思路去实现呢? 谢谢
刚刚接触JBPM的东东,对于审核历史的功能,我应该有哪些思路去实现呢? 谢谢
11 楼
macrochen
2008-07-22
引用
请问楼主是哪里的啊?
目前在昆明做项目
10 楼
macrochen
2008-07-22
引用
看那几个页面截图, 好像 dorado?
是的,是dorado+jbpm的项目
9 楼
crabboy
2008-07-18
请问楼主是哪里的啊?
8 楼
fcoffee
2008-06-20
看那几个页面截图, 好像 dorado?
7 楼
macrochen
2008-06-05
引用
在流程中有process state节点,此子流程的程序处理有需要注意的地方吗?
目前我还没有碰到特别需要注意的地方
6 楼
llandyl
2008-06-05
在流程中有process state节点,此子流程的程序处理有需要注意的地方吗?
5 楼
altr
2008-05-26
很好,谢谢!
4 楼
macrochen
2008-05-26
引用
Spring有个jBPM的module,挺有用的,可以用一下。特别是里面的JbpmTemplate。
从文章里可以看出一点,你们好像不太看文档,哈哈。很多问题都在文档里有写。
这个我当然是知道的,只是开始一直没搞懂state node怎么用,后来才明白过来, spring的jbpm module没看过,有时间看看
3 楼
yujianqiu
2008-05-25
Spring有个jBPM的module,挺有用的,可以用一下。特别是里面的JbpmTemplate。
从文章里可以看出一点,你们好像不太看文档,哈哈。很多问题都在文档里有写。
这句话虽然正确,但是有点本末倒置。state node会将当前的流程挂起,这是State的定义决定的,因此才有了State类的实现。
从文章里可以看出一点,你们好像不太看文档,哈哈。很多问题都在文档里有写。
引用
state node会将当前的流程挂起,这跟org.jbpm.graph.node.State类有关:
这句话虽然正确,但是有点本末倒置。state node会将当前的流程挂起,这是State的定义决定的,因此才有了State类的实现。
2 楼
Luzifer
2008-05-25
受益匪浅:)
1 楼
ttitfly
2008-05-24
很好,谢谢
发表评论
-
jBPM中Timer的使用
2008-07-27 13:02 6513[size=medium]jBPM中自带的 ... -
jBPM学习笔记(更新中...)
2008-07-17 17:59 3862[size=medium]★execution是一种类似有限状 ... -
将jbpm流程模型与业务模型结合的方式
2008-06-05 11:37 2231谋划中... -
使用JbpmContextFilter和手工创建关闭JbpmContext的选择
2008-06-05 11:37 1994谋划中... -
jBPM中的变量浅析
2008-06-04 13:51 6666在jbpm主要有两类变量, ... -
jBPM中JbpmContext.close()一个值得注意的问题
2008-06-03 01:49 5004在使用jBPM做开发的过程 ... -
一次部署多个jbpm 流程定义文件
2008-05-30 16:42 5438通常我们在部署流程定义文件都需要借助jbpm的eclipse ...
相关推荐
jbpm项目项目源码项目源码项目源码项目源码项目源码
jbpm项目实练,web版,有jar 有jsp,入门级别。能运行。
ssh+jbpm项目(某集团OA)
JBPM3总结:包括介绍和开发例子、流程等。
jBPM学习总结,涵盖jBPM4的各个基础知识点,及实例解析。
完整工作流JBPM项目实战全过程教程---项目详细讲解.doc
jbpm介绍jbpm介绍jbpm介绍jbpm介绍jbpm介绍jbpm介绍jbpm介绍jbpm介绍jbpm介绍jbpm介绍jbpm介绍jbpm介绍
JBPM笔记总结,最最经典的,初学者的必看
jbpm3.2开发总结.pdf
NULL 博文链接:https://zpchen.iteye.com/blog/258252
\jbpm简介\jbpm简介\jbpm简介\jbpm简介\jbpm简介
ssh+jbpm项目源码
jbpm jbpm4.3.jar DDDDDDDD
jbpm 数据库jbpm 数据库jbpm 数据库jbpm 数据库jbpm 数据库
jbpm使用案例,非常不错,大家都来看看吧。
jbpm应用开发指面(胡奇) jbpm4.3表结构和表字段说明 [jBPM开发指南].高杰.文字版 jBPM5_用户手册-中文版
通过查看JBPM的表,我们知道要实现流程监控功能就是把JBPM当中的JBPM_PROCESSDEFINITION(已发布的流程表),JBPM_PROCESSINSTANCE(流程实例表),JBPM_TASKINSTANCE(流程产生的任务实例表)这三张表串联起来就可以...
本文件从JBPM的原理、实现方法、实例等方面详细讲解了JBPM的原理,包括以下内容: 1、JBPM特色: 3 2、流程图的组成: 3 2.1流转 (TRANSITION) 3 2.2活动 (ACTIVITY) 3 3、所用到的表: 4 3.1资源库与运行时表结构:...
jbpm4源码jbpm4源码jbpm4源码