jbpm如何表示完成一个任务有多个疲软状态下完成射精

1015人阅读
JBPM(13)
同fork等一样是一种节点类型。任务节点是jbpm中一个非常重要的概念,一个任务节点可以包含若干个任务(开始状态start-state只能有一个任务),不同的任务可以由不同的人来完成,任务实例被分配给actorId来完成。任务实例有几个状态:创建、开始、结束,这些信息存在JBPM_TASKINSTANCE中。常用的方法:分派任务(指定处理人)-TaskInstance.assign(String)根据处理人查找任务实例-TaskMgmtSession.findTaskInstancesByActorId(&)任务创建-TaskMgmtInstance.createTaskInstance(&)任务开始-TaskInstance.start()任务结束TaskInstance.end(&)
任务可以被指定一个优先级,这个优先级在任务的实例创建时将被作为每个任务实例的初始优先级,任务实例的初始优先级可以在以后被修改。
如果多于一个任务实例与一个任务节点关联,流程开发者可以指定任务实例的完成怎样影响流程的继续。下面是可以给任务节点的signal属性设置的值:l&&&&&&& last:这是默认值。当最后一个任务实例完成时继续执行;当在节点入口处没有任务创建时,继续执行。l&&&&&&& last-wait:当最后一个任务实例完成时继续执行;当在节点入口处没有任务创建时,执行在任务节点等待,直到任务被创建。l&&&&&&& first:当第一个任务实例完成时继续执行;当在节点入口处没有任务创建时,继续执行。l&&&&&&& first-wait:当第一个任务实例完成时继续执行;当在节点入口处没有任务创建时,执行在任务节点等待,直到任务被创建。l&&&&&&& unsynchronized:总是继续执行,不管任务是否创建和完成。l&&&&&&& never:执行不再继续,不管任务是否创建和完成。
你可以在流程定义文件中定义任务,也可以在代码中定义:public class CreateTasks implements ActionHandler {&public void execute(ExecutionContext executionContext) throws Exception {&&& Token token = executionContext.getToken();&&& TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();&&&&& &&& TaskNode taskNode = (TaskNode) executionContext.getNode();&&& Task changeNappy = taskNode.getTask(&change nappy&);&&&& // 现在, 相同任务的两个任务实例被创建&&& tmi.createTaskInstance(changeNappy, token);&&& tmi.createTaskInstance(changeNappy, token);&}}
在Jbpm中,可以结合使用推模式和拉模式的任务分配。流程可以计算任务的责任人,并把它推到他/她的任务清单里;或者,任务可以被分配到参与者池,这种情况下,池中的每个参与者都可以拉出任务并把它放入参与者的个人任务清单。推模式:Assignable.setActorId(String actorId);TaskMgmtSession.findTaskInstances(String actorId)拉 模式:Assignable.setPooledActors(String[] actorIds);TaskMgmtSesion.findPooledTaskInstances(String actorId);TaskMgmtSession.findPooledTaskInstances(List actorIds)为了防止多个用户在同一个共享任务上工作,使用用户的actorId修改任务实例的actorId就可以了。这样,任务实例将不会出现在共享任务清单中,而只会存在于用户个人的任务清单里。设置任务实例的actorId为空(null),则会把任务实例放回共享任务里。
任务实例可以拥有它自己的变量,并且也可以&看到&流程变量。&task name=&clean ceiling&&&&controller&&&& &variable name=&a& access=&read& mapped-name=&x& /&&&& &variable name=&b& access=&read,write,required& mapped-name=&y& /&&&& &variable name=&c& access=&read,write& /&&&/controller&&/task&这里使用的是默认的控制器,也可以定义自己的控制器&task name=&clean ceiling&&&&controller class=&com.yourcom.CleanCeilingTaskControllerHandler&&&&& -- here goes your task controller handler configuration --&&/controller&&/task&
任务有四个标准的事件类型定义:task-create,task-assign,task-start,和task-end。
&?xml&version=&1.0&&encoding=&UTF-8&?&&process-definition&xmlns=&&&name=&yytest&&&&&&&swimlane&name=&banker&&&&&&&&&&&assignment&expression=&user(ernie)&/&&&&&&/swimlane&&&&&&swimlane&name=&casher&&&&&&&&&&&assignment&expression=&user(bert)&/&&&&&&/swimlane&&&&&&start-state&name=&start&&&&&&&&&&&transition&name=&&&to=&charge&/&&&&&&/start-state&&&&&&task-node&name=&charge&&signal=&first&&&&&&&&&&&task&name=&bank&&swimlane=&banker&/&&&&&&&&&&task&name=&cash&&swimlane=&casher&/&&&&&&&&&&transition&name=&&&to=&end&/&&&&&&/task-node&&&&&&end-state&name=&end&/&&/process-definition&
private&static&void&run(){&&&&&&&&JbpmContext&jbpmContext&=&jbpmConfiguration.createJbpmContext();&&&&&&&&try&...{&&&&&&&&&&&&long&processInstanceId&=1;&&&&&&&&&&&&processInstance&=&jbpmContext.loadProcessInstance(processInstanceId);&&&&&&&&&&&&Token&token&=&processInstance.getRootToken();&&&&&&&&&&&&System.out.println(token.getNode());&&&&&&&&&&&&token.signal();&&&&&&&&&&&&System.out.println(token.getNode());&&&&&&&&&&&&List&casherTasks&=&jbpmContext.getTaskMgmtSession().findTaskInstances(&ernie&);&&&&&&&&&&&&TaskInstance&cashertaskInstance&=&(TaskInstance)casherTasks.get(0);&&&&&&&&&&&&cashertaskInstance.start();&&&&&&&&&&&&cashertaskInstance.end();&&&&&&&&&&&&System.out.println(token.getNode());&&&&&&&&&&&&jbpmContext.save(processInstance);&&&&&&&&&&&&}finally&...{&&&&&&&&&&&&&&jbpmContext.close();&&&&&&&&&&&&}&&&&}&&&&...
-------------------------------------------------
StartState(start)TaskNode(charge)EndState(end)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:23170次
排名:千里之外
转载:14篇
评论:11条
(1)(1)(16)文章数:292
访问量:64599
注册日期:
阅读量:5863
阅读量:12276
阅读量:354247
阅读量:1051725
51CTO推荐博文
jBPM(java Business Process Management)是什么
是一种基于Java的、轻量级的、实现工作流管理的框架软件包。
jBPM能干什么
提供工作流的实现,帮助更好的进行BPM。
jBPM有什么,简介jBPM的Service API
1:ProcessEngine:流程引擎。并不负责具体的业务,而是用于获取各种Service。
2:RepositoryService:流程资源服务的接口,如流程定义发布、查询、删除等。
3:ExecutioService:用于操作流程实例的服务,可以进行流程实例发布、查询、流程推进、设置流程变量等操作。
4:TaskService:用于操作人工任务的服务,可以进行任务创建、查询、获取、提交完成、保存、删除等操作。
5:HistoryService:用于操作流程历史的服务,提供对流程历史库(就是已经完成的流程实例)的操作。比如:历史流程实例,历史活动实例等。
6:IdentityService:用于操作用户、用户组以及成员关系的服务
7:ManagementService:流程管理控制服务的接口,只提供异步工作(Job)相关的执行和查询操作。
1、下载干净的eclipse-jee-helios-SR2-win32.zip
2、在eclipse.ini中指定jdk的安装路径和工作空间使用的默认编码
D:/study/java/jdk/jdk1.6/bin/javaw.exe
-Dfile.encoding=UTF-8
3、安装gpd插件
拷贝jBPM-gpd-site.zip
【Help】-&【Install New Software】-&【Add】-&【Archive】
1、新建一个java工程
2、新建一个叫lib的文件夹
3、将jBPM4.4.zip包中所有jBPM依赖的jar包放入lib
${jBPM4}\lib\*.jar
4、将jBPM4本身的jar包放入lib
${jBPM4}\jBPM.jar
5、将ojdbc14.jar放入lib
6、替换原有lib中的slf4j-api.jar和slf4j-log4j12.jar
7、将以上jar包放入java工程的build path
1、将example中的下列配置文件拷贝到java项目的src目录下:
jBPM.cfg.xml、jBPM.hibernate.cfg.xml、jBPM.mail.properties、jBPM.mail.templates.xml、process_forms.css
2、在以上配置文件中的jBPM.hibernate.cfg.xml,实际上就是我们熟悉的hibernate.cfg.xml,这里,要修改为连接我们的数据库。
&property name=&connection.driver_class&&oracle.jdbc.driver.OracleDriver&/property&&property name=&connection.url&&jdbc:oracle:thin:@localhost:1521:orcl&/property& &property name=&connection.username&&test&/property& &property name=&connection.password&&test&/property& &property name=&dialect&&org.hibernate.dialect.Oracle9iDialect&/property&
3、在这里还需要强调,其中的一个配置:
&property name=&hibernate.hbm2ddl.auto&&create-drop&/property&
&&& 如果这个配置存在的话,那么每次操作数据库都会把原来的数据表干掉,然后重新建立。所以, 我们在第一次访问数据库的时候打开它,以后则关闭。
jPDL(JBoss jBPM Process Definition Language)
是构建于jBPM框架上的流程语言之一。在jPDL中提供了任务(tasks)、待处理状态(wait states)、计时器(timers)、自动处理(automated actions)…等术语,并通过图型化的流程定义,很直观地描述业务流程。
流程定义(ProcessDefinition)
就是对一个流程抽象的对象化定义。一套系统中,用户可以定义并保存多个流程定义实体,如:报销流程定义、请假流程定义、人事录用流程定义等。
是对流程中的过程环节/行为的抽象对象化定义。结点有两个主要职责:一,实现某个指定行为,这在jBPM中就是执行一段制定的Java代码;二,传递、维持流程的延续,直至达到最终结点。
流程实例(ProcessInstance)
流程实例是流程定义的运行时状态,它记录了一个流程运行的起始时间、结束时间等状态信息。
任务实例(Task)
用来描述一个任务实例对象,可以分配给指定的操作者处理,当任务完成后,将触发流程继续向下流转。任务实例的生命周期很简单,生成实例--&处理--&任务结束。
流程的开始
流程的结束
task活动一般用来处理涉及人机交互的活动,流程引擎会停在这里等待人工的操作。它的assignee属性用来指定任务分配给谁,可以使用变量来定义。
Transition
可以由task活动或decision活动建立,用来表示流程实例向下一个活动流转。
如何发布流程
//如果是读取默认的jbpm.cfg.xml文件
java代码:
ProcessEngine engine = Configuration.getProcessEngine();
//如果不是读取默认的jbpm.cfg.xml文件
ProcessEngine engine = new Configuration().setResource(&ccjbpm.cfg.xml&).buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createDeployment().addResourceFromClasspath(
&cn/javass/jbpm4/hello/hello.jpdl.xml&).deploy();
如何检索流程定义
java代码:
ProcessEngine processEngine = Configuration.getProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
List&ProcessDefinition& pdList = repositoryService.createProcessDefinitionQuery().list();
for (ProcessDefinition pd:pdList){
System.out.println(&id:&+pd.getId());
System.out.println(&name:&+pd.getName());
System.out.println(&version:&+pd.getVersion());
System.out.println(&deploymentId:&+pd.getDeploymentId());
System.out.println(&---------------&);
如何启动一个实例
java代码:
ProcessEngine processEngine = Configuration.getProcessEngine();
ExecutionService executionService = processEngine.getExecutionService();
Map map = new HashMap();
map.put(&pm&,&ProjectManager&);
map.put(&dm&, &DepartmentManager &);
map.put(&ceo&, &Manager&);
executionService.startProcessInstanceByKey(&MyProcess&,map);
如何检索流程实例
java代码:
ProcessEngine processEngine = Configuration.getProcessEngine();
ExecutionService executionService = processEngine.getExecutionService();
List&ProcessInstance& piList = executionService.createProcessInstanceQuery().list();
for (ProcessInstance pi : piList) {
System.out.println(&id:&+pi.getId());
System.out.println(&activeActivityNames:“
+pi.findActiveActivityNames());
System.out.println(&state:&+pi.getState());
System.out.println(&-----------------&);
如何检索出Task
java代码:
ProcessEngine processEngine = Configuration.getProcessEngine();
TaskService taskService = processEngine.getTaskService();
List&Task& list = taskService.createTaskQuery()
for(Task t : list){
System.out.println(&activityName=&+t.getActivityName()
+&,user=&+t.getAssignee()+&,id=&+t.getId());
如何完成task
java代码:
ProcessEngine processEngine = Configuration.getProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId = “70003”;//这个是流程运行中生成的任务id
Map map = new HashMap();
map.put(&dmResult&, 1);
map.put(&days&, 15);
pleteTask(taskId,map);
如何检索出历史的流程实例
java代码:
ProcessEngine engine = Configuration.getProcessEngine();
HistoryService hs = engine.getHistoryService();
List&HistoryProcessInstance& list =
hs.createHistoryProcessInstanceQuery().list();
for(HistoryProcessInstance hpi : list){
System.out.println(&state=&+hpi.getState()+& ,pdid=“
+hpi.getProcessDefinitionId()+&,piid=“
+hpi.getProcessInstanceId()
+&,startTime=&+hpi.getStartTime());
视频配套PPT,视频地址【 &】
本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)胡奇 的BLOG
用户名:胡奇
文章数:75
评论数:93
访问量:57339
注册日期:
阅读量:5863
阅读量:12276
阅读量:354247
阅读量:1051725
[匿名]51cto游客:
51CTO推荐博文
在我曾经见过的正式的第一个JBPM项目中,我注意到开发人员有时使用 executionContext 来放置很多流程的变量。为了控制执行流,向 executionContext 中增加变量是基本的法则,但是不管如何,不要被它诱惑的往里面放任何东西!例如:假设你正在设计一个复杂的售票系统:你可能需要存储一些关于执行者的附加信息,例如:名、姓、邮件。因此在执行上下文中你混合了业务变量和流程变量!
一个好的解决思路是:在一个EJB中构造这些字段,并且在你的 executionContext 中仅保持一个ticketid。
下面是一个使用Seam与业务流程进行交互的EJB的例子:
view plaincopy to clipboardprint?@Stateful&&&& @Name("TicketingSystem")&& public class TicketBean implements TicketBeanItf {&& @PersistenceContext(type=PersistenceContextType.EXTENDED)&& EntityM&& @In(create = true)&&&& @Out&&&& private T&& // We make this available to the business process&&&& @Out(scope=ScopeType.BUSINESS_PROCESS, required=false)&&&& long ticketId;&& @CreateProcess(definition="TroubleTicketing")&&&& public void createTicket() {&& em.persist(ticket);&&&& // Keep a reference to the ticketId in your biz process&&&& ticketId = ticket.getTicketId();&&&& }&& }&&& @Stateful& @Name("TicketingSystem")public class TicketBean implements TicketBeanItf {@PersistenceContext(type=PersistenceContextType.EXTENDED)EntityM@In(create = true)& @Out& private T// We make this available to the business process& @Out(scope=ScopeType.BUSINESS_PROCESS, required=false)& long ticketId;@CreateProcess(definition="TroubleTicketing")& public void createTicket() {em.persist(ticket);& // Keep a reference to the ticketId in your biz process& ticketId = ticket.getTicketId();& }}&& & type="application/x-shockwave-flash" width="14" height="15" src="" src="" flashvars="clipboard=%40Stateful%20%20%0A%40Name(%22TicketingSystem%22)%20%20%0A%20%20%20%0Apublic%20class%20TicketBean%20implements%20TicketBeanItf%20%7B%20%20%0A%20%20%20%0A%40PersistenceContext(type%3DPersistenceContextType.EXTENDED)%20%20%0AEntityManager%20em%3B%20%20%0A%20%20%20%0A%40In(create%20%3D%20true)%20%20%0A%40Out%20%20%0Aprivate%20Ticket%20ticket%3B%20%20%0A%20%20%20%0A%2F%2F%20We%20make%20this%20available%20to%20the%20business%20process%20%20%0A%40Out(scope%3DScopeType.BUSINESS_PROCESS%2C%20required%3Dfalse)%20%20%0Along%20ticketId%3B%20%20%0A%20%20%20%0A%40CreateProcess(definition%3D%22TroubleTicketing%22)%20%20%0A%20public%20void%20createTicket()%20%7B%20%20%0A%20%20%20%20em.persist(ticket)%3B%20%20%0A%20%20%20%20%2F%2F%20Keep%20a%20reference%20to%20the%20ticketId%20in%20your%20biz%20process%20%20%0A%20%20%20%20ticketId%20%3D%20ticket.getTicketId()%3B%20%20%0A%20%7D%20%20%0A%20%20%20%20%0A%7D%20%20%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="" width="14" height="15"& @Stateful& @Name("TicketingSystem")& && public class TicketBean implements TicketBeanItf {& && @PersistenceContext(type=PersistenceContextType.EXTENDED)& EntityM& && @In(create = true)& @Out& private T& && // We make this available to the business process& @Out(scope=ScopeType.BUSINESS_PROCESS, required=false)& long ticketId;& && @CreateProcess(definition="TroubleTicketing")& &public void createTicket() {& &&& em.persist(ticket);& &&& // Keep a reference to the ticketId in your biz process& &&& ticketId = ticket.getTicketId();& &}& &&& }& &
随意在执行上下文(executionContext)中添加领域变量,除了被当作一个不好的设计选择外,也会在很大程度上降低你流程运行的性能。
使用jBPM异常处理器,仅用来设置变量或者做错误通知 JBPM有一个内建的异常处理器,能够被应用在单一节点或者整个流程。
view plaincopy to clipboardprint?&exception-handler exception-class = "java.lang.Exception"&& &action class = "com.sample.handlers.BPMExceptionHandler"&& &/action&& &/exception-handler&&&&&& &exception-handler exception-class = "java.lang.Exception"&&action class = "com.sample.handlers.BPMExceptionHandler"&&/action&&/exception-handler&&&& &
&exception-handler exception-class="java.lang.Exception"&& &&& &action class="com.sample.handlers.BPMExceptionHandler"&&/action&&&&&&&& &/exception-handler&& 你或许曾经被诱惑在JBPM中使用异常处理机制来决策执行流,不要这样做!JBPM的机制并不完全与java的异常处理相似,在java中,一个捕获的异常能够对控制流产生影响。而在jBPM的案例中,控制流不能被jBPM的异常处理机制改变。异常可以被捕获或不捕获。不捕获的异常被扔给客户端(例如,调用 token.signal()方法的客户端)或者这个异常被jBPM异常处理器捕获。对于捕获的异常,graph execution 会当作没有异常发生继续执行。
使用异常处理器的最佳实践是,执行那些相关的action(设置变量,发生邮件,JMS消息等),然后或者继续graph的执行(你期望的行为)或者因为事务失败而重新扔出异常,并且结束当前节点回到开始的状态。依赖于被扔出的异常,在你的Action中捕获业务异常并且设置一些流程变量也是一个好的设计。然后你可以在流程中构造一个决策节点,用来选择一个特定的执行路径。
需要JBPM做失败转发?在一个集群的SLSB(stateless session bean)中封装JBPM的调用 jBPM是一个状态机:流程描述和运行时的状态被持久化到数据库中,但是在一个集群环境中,他们不会自动失败转发。如果一个集群节点失败了,这时正在执行的一些触发器(UI,JMS,重复执行的计时器)需要停止执行并且不得不重新启动。依赖于你所处的事务上下文,这些动作能够被自动执行(重新传递JMS消息,重新执行计时器)或者请求UI交互(如果集群节点宕机需要重启时,显示错误消息给用户)。
因此,当流程描述是持久化时,工作流的失败转发必须被手动执行。jBPM能够被用来构建一个完整的失败保护,可集群的支持失败转发的工作流解决方案,但是它不支持开箱即用。那么,在你的工作流中增加这些特性的最简单的方式是什么?对于大多数的案例,最佳的解决方案是在你的应用中用一个无状态的会话bean来封装jBPM API的调用,并且在最后构建集群。
给你的EJB增加集群能力一点也不复杂,参考下面的方案:
在尽可能的地方使用super states 一个Superstate是一组节点:它是一种将节点组合成相关集合的方便的方式,是在流程中实例阶段的表示。例如,一个应用程序能够分阶段组合流程中的所有节点。动作(Action)可以被关联到superstate事件上。一个重要的意义就是一个令牌(token)能够在给定的时间上被多层嵌套。这可以方便地来检查一个流程是否被执行了,例如在开始阶段。
因此,当每个状态都代表着一个流程的阶段时,将流程拆分出super states是一种好的设计,但是为什么我提倡对super states的使用还有更多的理由:
JBPM是一个状态机并且本身没有交付一个内建的图形化环境。官方的Eclipse插件,可以让你来图形化的流程建模,但是它不是在市场上最好的BPM前端工具:图标太大,太丑陋,并且你不能够自己为不同的节点类型来定制图标。如果你曾经用JBPM画一个有100个节点的流程,你可能也做我所做的事情了:因为流程的图片很大并且很杂乱,我从JBPM中自己设计了一个前端展现层。
如果你不希望为JBPM设计一个新的前端,那么尽可能广泛地使用superstates,它将使你的流程(图)更可读,并且当你展现一个5页的流程图时你老板不会晕。
尝试扩展JBPM的API而不是搞乱复杂的流程建模 有时候开发人员(我也是)不去寻找更简单的解决方案,或许用jBPM内建的节点来建模流程而导致一个不必要的复杂流程。
想更简单……
jBPM是非常易扩展的(action handlers,定制节点类型)并且有时比用存在的节点做简单的建模还要容易!这可以使得事情没有那么复杂。
例如:假设你有这样一个需求,在一个依赖于地理定位的特定泳道内指派一个任务。(如果一个任务发生在纽约,它指派给用户A,如果它发生在芝加哥那么指派给用户B)
拿到 org.jbpm.taskmgmt.def.Task.java 这个类并且增加下述的字段和方法:
view plaincopy to clipboardprint?private String taskL&&&& public String getTaskLocation() {&&&& return& taskL&&&& }&&&& public void setTaskLocation(String taskLocation){&&&& this.taskLocation = taskL&&&& }&& private String taskL& public String getTaskLocation() {& return& taskL& }& public void setTaskLocation(String taskLocation){& this.taskLocation = taskL& }&
private String taskL&public String getTaskLocation() {&& return taskL}public void setTaskLocation(String taskLocation){&& this.taskLocation = taskL}&
现在为 Task.java 修改hibernate配置文件,在 Task.hbm.xml 中:
view plaincopy to clipboardprint?&property name="taskLocation" column= "TASKLOCATION_"&&/property&& &property name="taskLocation" column= "TASKLOCATION_"&&/property&
最后修改 JpdlXmlReader.java 以使得当流程从数据库中读入时新的属性被注入到Task类中。
view plaincopy to clipboardprint?String taskLocation = taskElement.attributeValue("taskLocation");&& if (taskLocation==null) {&& &&&&&&&& taskLocation = taskElement.attributeValue("taskLocation");&& }&& &&&&&& if (taskLocation != null){&& &&&&&&&&& task.setLocation(taskLocation);&& }& String taskLocation = taskElement.attributeValue("taskLocation");if (taskLocation==null) {&&&&&&&& taskLocation = taskElement.attributeValue("taskLocation");}&&& if (taskLocation != null){&&&&&&&&& task.setLocation(taskLocation);}&
String taskLocation = taskElement.attributeValue("taskLocation");
if (taskLocation==null) {&&&&&&&& taskLocation = taskElement.attributeValue("taskLocation");}&&& if (taskLocation != null){&&&&&&&&& task.setLocation(taskLocation);}
另一个定制的例子可以应用到你的查询中。假设你想用很多规则来过滤你的任务:考虑一个用JSF来做渲染的任务列表和一个任务过滤窗口,这个窗口中你可以按照优先级、日期、执行人、任务名称等来过滤任务。
一个不会使得事情更复杂的、实现它的方式是,给任务实例增加过滤器:仅仅是打开任务实例的hibernate文件并且添加一些hibernate过滤器:
view plaincopy to clipboardprint?&filter name= "filterPriority" condition= ":paramPriority = PRIORITY_" /&&&&&&&&& &filter name="filterDesc" condition= ":paramDesc = DESCRIPTION_" /&&&&&&&&&&&&& &filter name="filterId" condition= "str(ID_) LIKE (:paramId) " /&&&&&&&&& &filter name="filterCreate" condition= "CREATE_ BETWEEN :paramFrom and :paramTo" /&&& &filter name= "filterPriority" condition= ":paramPriority = PRIORITY_" /&&&&&& &filter name="filterDesc" condition= ":paramDesc = DESCRIPTION_" /&&&&&&&&&& &filter name="filterId" condition= "str(ID_) LIKE (:paramId) " /&&&&&& &filter name="filterCreate" condition= "CREATE_ BETWEEN :paramFrom and :paramTo" /&&
注意,传递给过滤器的参数以“:”开始,而其它的字段(像_ID)属于TaskInstance。然后当你填充你的数据库时,使被选择的过滤器生效:
view plaincopy to clipboardprint?String sql& = "from org.jbpm.taskmgmt.exe.TaskInstance";&& session.enableFilter("filterPriority").setParameter("paramPriority","2");&& Query queryParent = session.createQuery(sql);&&&&& List list = queryParent.list();&& Iterator iter = list.iterator();&& &while (iter.hasNext()) {&&&&& & TaskInstance taskInstance = (TaskInstance)iter.next();&& &}& String sql& = "from org.jbpm.taskmgmt.exe.TaskInstance";session.enableFilter("filterPriority").setParameter("paramPriority","2");Query queryParent = session.createQuery(sql);&& List list = queryParent.list();Iterator iter = list.iterator();&while (iter.hasNext()) {&& & TaskInstance taskInstance = (TaskInstance)iter.next();&}
&filter name="filterPriority"& condition=":paramPriority = PRIORITY_"/&&&& &&& &filter name="filterDesc"&&&&& condition=":paramDesc = DESCRIPTION_"/&&&&&&&& &&& &filter name="filterId"&&&&&&& condition="str(ID_) LIKE (:paramId) "/&&&& &&& &filter name="filterCreate"&&& condition="CREATE_ BETWEEN :paramFrom and :paramTo"/&& String sql& = "from org.jbpm.taskmgmt.exe.TaskInstance";session.enableFilter("filterPriority").setParameter("paramPriority","2");Query queryParent = session.createQuery(sql);&& List list = queryParent.list();Iterator iter = list.iterator();&while (iter.hasNext()) {&& & TaskInstance taskInstance = (TaskInstance)iter.next();&}如果你有复杂的规则,雇用一个Drools开发人员 首先要理解:
一个工作流引擎(或者传统的面向图的编程)是关于制定一个代表执行的图。节点可以展现为等待状态。
一个规则引擎是关于指定一套规则然后为指定的一套事实库应用一个推理算法。
Drools怎样同JBPM相配合呢?一个最佳的实践是用JBPM来使一个规则引擎中的Handlers中的全部或部分逻辑具体化。换句话说,JBPM引擎能够由Drools规则引擎来驱动。
结合其它观点,这一做法也并非适用于所有情况,所以问问自己几件事:
我的java Action Handlers 有多复杂?如果你仅仅需要从数据库中读取一些数据,而不需要更多的,这可能不适合用一个规则引擎。然而,在使用java来实现一个处理大量业务规则的场合,当使用JBPM引擎做你的流程管理时是值得考虑用Drools的。这是因为大多数的应用开发随着时间会越来越复杂,而Drools会让你轻松地应付这些,特别是如果你的应用的生命周期比较长。更进一步,Drools通过在一个或多个很容易配置的XML文件中指定业务规则可以帮助你对付将来的业务规则变化。
Drools的另一个得分点是,Drools“指引”开发人员正确地编写代码来“做正确的事情”。同时,规则比编码更容易阅读,因此你的员工在“阅读业务”时会更舒服。
更进一步,在正确使用的情况下,Drools能记住的不仅仅是信息,而且还有以前使用这些信息的测试结果,从而给整个应用一个快速的提升。
用还是不用BPEL? BPEL是一个XML语言,用来描述长期运行的web服务的交互。它主要被用来集中地编排消息交换,因此在SOA中是一个关键的要素。
BPEL与JPDL有什么共同点呢?
两个语言都可以描述过程 同外部代理交互 对于活动的调度 异常处理 错误恢复 即使它们有一些共同点,但这些元素的具体表达式导致不同的受众,讨论它们对于过程的描述:
JPDL用更加简单的语义来描述组织过程 BPEL用复杂的场景来描述结构化的组成 而与外部代理的交互也被不同地实现:
BPEL是基于面向文档的,因此可以在整个公司范围上使用 JPDL是面向对象的,因此它可以作为公司应用组件的主干 BPEL将人之间的交互代理给 Partner Service 实现 jPDL提供集成的任务管理 那么我应该什么时候使用BPEL?
当你需要你的流程很轻便的伸展到java平台之外――BPEL流程能够在基于java平台的服务器或任何其它的软件平台(例如.NET)上被执行。这一点在使用不同平台的合作伙伴之间进行商业交互的场景中是特别重要的。 当没有直接的人员涉及(即无人工干预的流程),同时你更需要对长时间运行的业务流程很好支持的情况下。 当你需要以一个相对简单的方式取得事务补偿时。在已经完全成功的业务流程中的补偿,或者取消步骤是业务流程中最重要的概念。补偿的目标是撤销,即消除一个业务流程中已被放弃的一部分已经被执行的节点所造成的影响。 当这些条件不满足时使用JPDL。
本文来自CSDN博客,转载请标明出处:650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' border="0" alt="" src="/attachment/075066.jpg" />
因此,当每个状态都代表着一个流程的阶段时,将流程拆分出super states是一种好的设计,但是为什么我提倡对super states的使用还有更多的理由:
JBPM是一个状态机并且本身没有交付一个内建的图形化环境。官方的Eclipse插件,可以让你来图形化的流程建模,但是它不是在市场上最好的BPM前端工具:图标太大,太丑陋,并且你不能够自己为不同的节点类型来定制图标。如果你曾经用JBPM画一个有100个节点的流程,你可能也做我所做的事情了:因为流程的图片很大并且很杂乱,我从JBPM中自己设计了一个前端展现层。
如果你不希望为JBPM设计一个新的前端,那么尽可能广泛地使用superstates,它将使你的流程(图)更可读,并且当你展现一个5页的流程图时你老板不会晕。
尝试扩展JBPM的API而不是搞乱复杂的流程建模 有时候开发人员(我也是)不去寻找更简单的解决方案,或许用jBPM内建的节点来建模流程而导致一个不必要的复杂流程。
想更简单……
jBPM是非常易扩展的(action handlers,定制节点类型)并且有时比用存在的节点做简单的建模还要容易!这可以使得事情没有那么复杂。
例如:假设你有这样一个需求,在一个依赖于地理定位的特定泳道内指派一个任务。(如果一个任务发生在纽约,它指派给用户A,如果它发生在芝加哥那么指派给用户B)
拿到 org.jbpm.taskmgmt.def.Task.java 这个类并且增加下述的字段和方法:
view plaincopy to clipboardprint?private String taskL&&&& public String getTaskLocation() {&&&& return& taskL&&&& }&&&& public void setTaskLocation(String taskLocation){&&&& this.taskLocation = taskL&&&& }&& private String taskL& public String getTaskLocation() {& return& taskL& }& public void setTaskLocation(String taskLocation){& this.taskLocation = taskL& }&
private String taskL&public String getTaskLocation() {&& return taskL}public void setTaskLocation(String taskLocation){&& this.taskLocation = taskL}&
现在为 Task.java 修改hibernate配置文件,在 Task.hbm.xml 中:
view plaincopy to clipboardprint?&property name="taskLocation" column= "TASKLOCATION_"&&/property&& &property name="taskLocation" column= "TASKLOCATION_"&&/property&
最后修改 JpdlXmlReader.java 以使得当流程从数据库中读入时新的属性被注入到Task类中。
view plaincopy to clipboardprint?String taskLocation = taskElement.attributeValue("taskLocation");&& if (taskLocation==null) {&& &&&&&&&& taskLocation = taskElement.attributeValue("taskLocation");&& }&& &&&&&& if (taskLocation != null){&& &&&&&&&&& task.setLocation(taskLocation);&& }& String taskLocation = taskElement.attributeValue("taskLocation");if (taskLocation==null) {&&&&&&&& taskLocation = taskElement.attributeValue("taskLocation");}&&& if (taskLocation != null){&&&&&&&&& task.setLocation(taskLocation);}&
String taskLocation = taskElement.attributeValue("taskLocation");
if (taskLocation==null) {&&&&&&&& taskLocation = taskElement.attributeValue("taskLocation");}&&& if (taskLocation != null){&&&&&&&&& task.setLocation(taskLocation);}
另一个定制的例子可以应用到你的查询中。假设你想用很多规则来过滤你的任务:考虑一个用JSF来做渲染的任务列表和一个任务过滤窗口,这个窗口中你可以按照优先级、日期、执行人、任务名称等来过滤任务。
一个不会使得事情更复杂的、实现它的方式是,给任务实例增加过滤器:仅仅是打开任务实例的hibernate文件并且添加一些hibernate过滤器:
view plaincopy to clipboardprint?&filter name= "filterPriority" condition= ":paramPriority = PRIORITY_" /&&&&&&&&& &filter name="filterDesc" condition= ":paramDesc = DESCRIPTION_" /&&&&&&&&&&&&& &filter name="filterId" condition= "str(ID_) LIKE (:paramId) " /&&&&&&&&& &filter name="filterCreate" condition= "CREATE_ BETWEEN :paramFrom and :paramTo" /&&& &filter name= "filterPriority" condition= ":paramPriority = PRIORITY_" /&&&&&& &filter name="filterDesc" condition= ":paramDesc = DESCRIPTION_" /&&&&&&&&&& &filter name="filterId" condition= "str(ID_) LIKE (:paramId) " /&&&&&& &filter name="filterCreate" condition= "CREATE_ BETWEEN :paramFrom and :paramTo" /&&
注意,传递给过滤器的参数以“:”开始,而其它的字段(像_ID)属于TaskInstance。然后当你填充你的数据库时,使被选择的过滤器生效:
view plaincopy to clipboardprint?String sql& = "from org.jbpm.taskmgmt.exe.TaskInstance";&& session.enableFilter("filterPriority").setParameter("paramPriority","2");&& Query queryParent = session.createQuery(sql);&&&&& List list = queryParent.list();&& Iterator iter = list.iterator();&& &while (iter.hasNext()) {&&&&& & TaskInstance taskInstance = (TaskInstance)iter.next();&& &}& String sql& = "from org.jbpm.taskmgmt.exe.TaskInstance";session.enableFilter("filterPriority").setParameter("paramPriority","2");Query queryParent = session.createQuery(sql);&& List list = queryParent.list();Iterator iter = list.iterator();&while (iter.hasNext()) {&& & TaskInstance taskInstance = (TaskInstance)iter.next();&}
&filter name="filterPriority"& condition=":paramPriority = PRIORITY_"/&&&& &&& &filter name="filterDesc"&&&&& condition=":paramDesc = DESCRIPTION_"/&&&&&&&& &&& &filter name="filterId"&&&&&&& condition="str(ID_) LIKE (:paramId) "/&&&& &&& &filter name="filterCreate"&&& condition="CREATE_ BETWEEN :paramFrom and :paramTo"/&& String sql& = "from org.jbpm.taskmgmt.exe.TaskInstance";session.enableFilter("filterPriority").setParameter("paramPriority","2");Query queryParent = session.createQuery(sql);&& List list = queryParent.list();Iterator iter = list.iterator();&while (iter.hasNext()) {&& & TaskInstance taskInstance = (TaskInstance)iter.next();&}如果你有复杂的规则,雇用一个Drools开发人员 首先要理解:
一个工作流引擎(或者传统的面向图的编程)是关于制定一个代表执行的图。节点可以展现为等待状态。
一个规则引擎是关于指定一套规则然后为指定的一套事实库应用一个推理算法。
Drools怎样同JBPM相配合呢?一个最佳的实践是用JBPM来使一个规则引擎中的Handlers中的全部或部分逻辑具体化。换句话说,JBPM引擎能够由Drools规则引擎来驱动。
结合其它观点,这一做法也并非适用于所有情况,所以问问自己几件事:
我的java Action Handlers 有多复杂?如果你仅仅需要从数据库中读取一些数据,而不需要更多的,这可能不适合用一个规则引擎。然而,在使用java来实现一个处理大量业务规则的场合,当使用JBPM引擎做你的流程管理时是值得考虑用Drools的。这是因为大多数的应用开发随着时间会越来越复杂,而Drools会让你轻松地应付这些,特别是如果你的应用的生命周期比较长。更进一步,Drools通过在一个或多个很容易配置的XML文件中指定业务规则可以帮助你对付将来的业务规则变化。
Drools的另一个得分点是,Drools“指引”开发人员正确地编写代码来“做正确的事情”。同时,规则比编码更容易阅读,因此你的员工在“阅读业务”时会更舒服。
更进一步,在正确使用的情况下,Drools能记住的不仅仅是信息,而且还有以前使用这些信息的测试结果,从而给整个应用一个快速的提升。
用还是不用BPEL? BPEL是一个XML语言,用来描述长期运行的web服务的交互。它主要被用来集中地编排消息交换,因此在SOA中是一个关键的要素。
BPEL与JPDL有什么共同点呢?
两个语言都可以描述过程 同外部代理交互 对于活动的调度 异常处理 错误恢复 即使它们有一些共同点,但这些元素的具体表达式导致不同的受众,讨论它们对于过程的描述:
JPDL用更加简单的语义来描述组织过程 BPEL用复杂的场景来描述结构化的组成 而与外部代理的交互也被不同地实现:
BPEL是基于面向文档的,因此可以在整个公司范围上使用 JPDL是面向对象的,因此它可以作为公司应用组件的主干 BPEL将人之间的交互代理给 Partner Service 实现 jPDL提供集成的任务管理 那么我应该什么时候使用BPEL?
当你需要你的流程很轻便的伸展到java平台之外――BPEL流程能够在基于java平台的服务器或任何其它的软件平台(例如.NET)上被执行。这一点在使用不同平台的合作伙伴之间进行商业交互的场景中是特别重要的。 当没有直接的人员涉及(即无人工干预的流程),同时你更需要对长时间运行的业务流程很好支持的情况下。 当你需要以一个相对简单的方式取得事务补偿时。在已经完全成功的业务流程中的补偿,或者取消步骤是业务流程中最重要的概念。补偿的目标是撤销,即消除一个业务流程中已被放弃的一部分已经被执行的节点所造成的影响。 当这些条件不满足时使用JPDL。
原文:/en/jbpm/106-jbpm-best-practices.html
了这篇文章
类别:┆阅读(0)┆评论(0)}

我要回帖

更多关于 亚马逊产品状态未完成 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信