摘要:在工作流引擎的设计过程中,如何确保引擎兼具内核的轻巧性和外延的强大性,是一直困扰我们的关键设计问题。本文在系统地研究jBPM的建模语言和体系结构的基础上,提炼出jBPM针对上述问题的解决方案:
¨ 在流程静态建模层面,建模语言jPDL系统地、全面地支持自定义构件的挂接;适度分离粗略的业务流程定义和精确的技术流程定义,并确保软件二次开发人员可以在业务分析人员给出的业务流程模型的基础上进行精化,保持技术流程基于业务流程的延续性。
¨ 在流程动态执行层面,从流程执行支撑、流程功能增强两个方面系统地、全面地设置可拔插(pluggable)的扩充点:
ü 流程执行支撑扩充点包括:流程定义适配,组织模型及任务分派适配,流程实例存储服务适配,外部应用系统适配。
ü 流程功能增强扩充点包括:任务策略扩充,事件监听扩充,日程调度扩充,工作日历扩充,安全控制扩充。
1 流程静态建模机制的扩充性
在jBPM的流程定义语言jPDL中,定义了多种扩充点,包括:条件路由,业务逻辑扩展,任务分派。
条件路由通过建模语言中的decision节点来实现。有两种路由方法,一种在静态建模时定义路由条件,另一种由代理类的Java代码在运行时动态决定路由。
¨ 静态路由:在decision节点中说明Beanshell表达式。Beanshell是jBPM采用的一种script语言。
例1-1:
<decision name='decision'>
<transition name='important lead' to='harras them'>
<condition expression = ‘……’ />
</ transition>
<transition name='lead' to='put it in the lead db'>
<condition expression = ‘……’ />
</ transition>
<transition name='beggars' to='forget about it'>
<condition expression = ‘……’ />
</ transition>
</decision>
¨ 动态路由:在decision节点中说明代理(delegation)Java类,由该类在流程实例运行过程中决定路由。
例1-2:
<decision name='decision'>
<handler class='org.jbpm.jpdl.exe.DecisionHandlerTest'/>
<transition name='important lead' to='harras them' />
<transition name='lead' to='put it in the lead db'/>
<transition name='beggars' to='forget about it'/>
</decision>
jBPM的建模语言jPDL主要通过其event机制提供业务逻辑扩充点。jPDL有预定义的event类型,主要包括:节点进入(node-enter)、节点离开(node-leave)、流程启动(process-start)、流程结束(process-end)、任务创建(task-create)、 任务分派(task-assign)、任务启动(task-start)、定时器事件等。二次开发人员也可以自定义event类型。每个event都可以与action列表绑定。action是一个Java类,其中可以描述定制的业务逻辑。在流程实例运行过程中,当系统捕获到event时,执行相应的action列表。
jPDL提供的业务逻辑扩充点还不止于上述event机制。在node和transition中,均可以定义action,通过action可以对应二次开发人员定制的Java类,从而实现基本工作流系统的业务逻辑扩充。
¨ 在流程建模时静态地定义任务分派目标:
ü 针对任务(task)的分派:
例1-3:
<task name="evaluate web order">
<assignment expression="user(ernie)" />
</swimlane>
ü 针对泳道(swimlane)的分派:
例1-4:
<swimlane name="salesman">
<assignment expression="group(sale)" />
</swimlane>
说明:“泳道”是指,在一个工作流模型中执行者相同的任务构成的集合。
¨ 通过扩充点动态地定义任务分派目标:
例1-5:
<task name='change nappy'
<assignment class='org.jbpm.tutorial.taskmgmt.NappyAssignmentHandler'
</task>
上例中,实际的任务分派动作由用户自定义类NappyAssignmentHandler完成。该类必须实现jBPM的标准接口AssignmentHandler。
在流程定义(process-definition)、节点(node)和迁移(transition)中,均可以定义异常处理器(exception-handler)。异常处理器的内容为一系列的actions,每个action再对应二次开发人员定义的Java类。
2 流程动态执行机制的扩充点
2.1 流程执行支撑扩充点
2.1.1组织模型及任务分派适配
因为组织模型与任务分派紧密相关,所以工作流引擎必须考虑组织模型;但是,组织模型与应用环境也是紧密关联的,所以很难给出标准的、可复用的组织模型。为此,jBPM采用以下递进策略:
¨ jBPM利用其identity compoment来提供对最简单的组织模型的支持,该组织模型仅描述用户、组以及它们之间的关系,其类图如下:
上图中,User代表用户或服务,Group代表一类User。Group可以有不同的类型。Membership描述了User和Group之间的多对多关系,也可以用来指示User在Group中扮演的角色。
为了描述基于上述简单组织模型的任务分派,jBPM定义了一种任务分派表达式,用于在流程建模时静态地定义任务执行者。任务分派表达式的语法如下:
<assignment-exp> ::= <first-term> [--> next-term] 0..*
<first-term> ::= previous |
swimlane(swimlane-name) |
variable(variable-name) |
user(user-name) |
group(group-name)
<next-term> ::= group(group-type) |
member(role-name)
例如,previous --> group(‘hierarchy’) --> member(‘boss’) 表示:前一任务执行者所在的类型为hierarchy的组中角色为boss的员工。
¨ 在实际应用时,用户的组织机构几乎肯定会比jBPM identity compoment提供的组织模型复杂。所以,二次开发人员可以将实际的组织模型映射到上述简单模型。映射的方法是:填充jBPM identity compoment规定的三张数据库表格:User,Group和Membership。
¨ 如果二次开发人员觉得实现上述映射有困难,那么可以完全抛开identity compoment,转而采用任务分派的代理(delegation)机制,即,提供一个任务分派代理类,在该类的Java代码中实现任务分派。jBPM要求代理类必须实现org.jbpm.taskmgmt.def.AssignmentHandler接口。见例1-5。
流程实例存储服务是指为工作流引擎在流程实例运行过程中提供信息保存和读取的服务机制。为了实现DBMS无关性,jBPM采用以下递进策略:
¨ 缺省情况下,jBPM采用Hibernate实现流程实例存储服务。二次开发人员可以通过修改Hibernate的映射和配置文件,就可以根据需要适应特殊的数据库需求。
¨ jBPM3.1在存储服务机制中引进了新的扩充点:二次开发人员可以在代码中指定JDBC connection、Hibernate session和Hibernate session factory。一旦通过以下持久服务资源注入方法来设置自定义的connection、session(factory),jBPM会用它们替代上述配置文件中的资源。
ü JbpmContext.setConnection(java.sql.Connection connection)
ü JbpmContext.setSession(org.hibernate.Session
session)
ü JbpmContext.setSessionFactory(org.hibernate.SessionFactory sessionFactory
);
工作流系统与外部应用的挂接通过建模语言中的action机制来实现。Action可以定义在流程(process)中、节点(node)中、迁移(transition)中、事件(event)中,以及定时器(timer)中。在action的定义中可以指定自定义的Java类,在此Java类中调用外部应用的功能。
例2-1:
<process-definition name="Hi Process">
<start-state name="start">
<event type="node-leave">
<action name="Hi action" class="com.aaa.HiActionHandler"
config-type="bean">
<city>Shanghai</city>
<rounds>2</rounds>
</action>
</event>
<transition name="tr" to="next_state"></transition>
</start-state>
……
</process-definition>
在上例中,流程实例运行时一旦发生从节点“start”出发的迁移,嵌于事件中的action将被执行,从而实现对类com.aaa.HiActionHandler中Java代码的调用。在该类的代码中,二次开发人员可以实现与外部应用的互操作。
jBPM的建模语言允许通过XML配置向action中的自定义类传递初始参数,例如例2-1中的参数“city”和“rounds”。在action自定义类中,也可以通过jBPM API实现对工作流变元的读写。
2.2 流程功能增强扩充点
jBPM在任务策略方面的扩充点包括:任务分配、任务执行与提交时任务与流程之间的信息传递。
¨ 任务分配扩充点:“1.3 任务分派”已经描述了任务分派策略的扩充点,即,可以在流程建模时给出基于identity compoment简单组织模型的表达式,静态地定义任务分派目标;也可以指定任务分派代理类,由该代理类在流程实例运行过程中动态确定任务分派目标。除上述扩充点外,jBPM还支持两种任务分配模式:push模式和pull模式。二次开发人员可以根据需要选择自己的分配模式。
ü 在push模式下,工作流引擎(或者其任务分派模块)直接将任务实例与具体的actorId相关联,引擎自动将任务实例push到actor的任务列表中。如果前述分派表达式的计值结果为单个actorId,或者二次开发人员指定任务分派代理类使用Assignable.setActorId(String actorId),那么jBPM系统采用push模式完成任务分配。否则,如果前述分派表达式的计值结果为多个actorId构成的集合,或者二次开发人员指定任务分派代理类使用Assignable. setPooledActors(String[] pooledActors),那么jBPM系统采用下述的pull模式完成任务分配。
ü 在pull模式下,工作流引擎(或者其任务分派模块)将任务实例与多个actorId相关联,这些actorId构成的集合称为pooledActors。jBPM使该任务实例对pool中所有actor可见,但是引擎并不将任务实例推送到这些actor的任务列表中,而是等待pool中的某个actor将该任务实例pull进自己的任务列表中。一旦任务实例被pool中某个actor pull,引擎将该任务实例设置成对pool中其他actor不可见。
¨ 任务与流程实例信息交流扩充点:在任务执行时,可能需要读、写流程变量;在任务完成并提交时,可能需要写流程变量。为此,jBPM提供了“任务变量”的概念。在某些情况下,任务变量和流程变量并非简单的一一对应关系,例如,三个流程变量代表三个月的销售额,任务变量只需要它们的平均值。为实现任务与流程实例之间的信息交流,jBPM设置了任务控制器机制。该机制也采用递进模式:首先,jBPM提供基本(默认)的任务控制器;如果不敷使用,二次开发人员可以使用自定义的任务控制器。jBPM的任务控制器机制在流程变量和任务变量之间架起了一座桥梁。
ü 使用jBPM默认的任务控制器:
<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>
上例中,任务控制器将流程变量a、b、c依次映射为任务变元x、y、c;x从a中读取初值,但在任务完成、提交时x的新值并不写回至a;y从b中读取初值,并在任务完成、提交时将y的新值写回至b;至于c,在任务执行时直接使用流程变量c,并在任务完成、提交时将c的新值带回至流程实例执行环境。
ü 使用自定义的任务控制器:
<task name="clean ceiling">
<controller class="com.yourcom.CleanCeilingTaskControllerHandler">
-- here goes your task controller handler configuration --
</controller>
</task>
二次开发人员提供的自定义任务控制器必须实现以下接口:
public interface TaskControllerHandler extends Serializable
{
List getTaskFormParameters(TaskInstance taskInstance);
void submitParameters(Map parameters, TaskInstance taskInstance);
}
其中,getTaskFormParameters函数负责从流程实例运行环境读取数据至任务执行环境;submitParameters则负责将任务执行环境中的数据提交至流程实例运行环境。
jBPM的事件由工作流模型图形元素(node、transition、superstate和process-definition等)和事件类型唯一确定。jBPM定义了一系列与工作流模型图形元素相关联的事件,例如,流程实例运行过程中,可以触发节点进入(node-enter)、节点离开(node-leave)、流程启动(process-start)、流程结束(process-end)、任务创建(task-create)、 任务分派(task-assign)、任务启动(task-start)等事件。
在静态建模时,jBPM的事件均与actions绑定。事件的触发将导致相应actions的执行。如“1.2业务逻辑扩展”所述,这是jBPM支持业务逻辑扩展的主要手段。
<process-definition>
<event type="node-enter">
<script>
System.out.println("this script is entering node "+node);
</script>
</event>
...
</process-definition>
jBPM的事件传播采用自底向上的模式,关联于某个图形元素的事件首先发往该图形元素;在执行完该图形元素中针对该类事件指定的actions之后,事件继续传向该图形元素的父元素。jBPM对图形元素之间的父子关系定义如下:超状态(superstate)是包含于超状态中的图形元素(例如node,transition等)的父元素;process-definition是所有顶级图形元素(不位于任何超状态中)的父元素。
二次开发人员可以自定义事件类型,并通过GraphElement.fireEvent(String eventType, ExecutionContext executionContext)来发送事件。自定义事件遵循与jBPM标准事件相同的事件处理逻辑和事件传播逻辑。
<process-definition>
<event type="custom-event">
<action name="custom-action" class=" com.aaa.CustomEventHandler "/>
</event>
...
</process-definition>
jBPM通过定时器(timer)实现日程调度。在node中加入timer元素,即可实现基于定时器的节点执行监控。
<state name='catch crooks'>
<timer name='reminder' duedate='3 business hours' repeat='10 business minutes'
transition='time-out-transition' >
<action class='the-remainder-action-class-name' />
</timer>
...
</state>
在上例中,一旦流程实例运行进入state 'catch crooks',定时器reminder即被创建。该定时器在3个工作小时到期,到期后马上执行action类中的Java代码,然后实施time-out-transition迁移。
通过在事件的action中加入create-timer和cancel-timer动作,可以分别实现事件对定时器的创建和取消。
jBPM的工作日历提供业务时间信息,并可用于计算任务和定时器的超时时间。jBPM缺省提供的属性文件jbpm.business.calendar.properties 定义了工作日历的配置信息,例如,上、下班时间,节假日,日期/时间格式等。
二次开发人员可以通过修改该属性文件来实现对工作日历的定制。
安全控制机制包括用户认证和授权控制。jBPM3.0尚未实现完整的缺省安全控制机制,但是其框架为未来的安全控制机制提供了扩充点。
¨ 用户认证。jBPM认为其工作流引擎一定会运行于特定容器,例如WebApp,EJB,SWING等,所以它认为引擎的运行环境必须实现用户认证功能,而jBPM引擎只需获取认证的结果(即通过认证的actorId)即可。jBPM通过接口Authenticator中的getAuthenticatedActorId()函数获取通过认证的actorId。二次开发人员可以在配置文件中指定自定义的Authenticator接口的实现类。
¨ 授权控制。jBPM引擎通过接口Authorizer中的checkPermission(Permission permission, ProcessDefinition processDefinition, Token token)判别用户是否具有相关操作的权限。jBPM3.0定义了6种操作权限:创建流程实例权限(CreateProcessInstancePermission),部署流程实例权限(DeployProcessPermission),任务分派权限(TaskAssignPermission)、结束任务权限(EndTaskPermission)、查看任务参数权限(ViewTaskParametersPermission)、提交任务参数权限(SubmitTaskParametersPermission)。类似于前述的用户认证扩充点,二次开发人员可以在配置文件中指定自定义的Authorizer接口的实现类,从而实现符合特定用户需求的授权控制机制。
分享到:
相关推荐
紧接着,书中探讨了UML的可扩展性,包括公共机制和扩展机制,让读者理解UML不仅是一种静态的标准,还具有适应不同需求的灵活性。 UML建模语言由几个基本构成元素组成,如结构元素(类、接口、构件和结点等)、行为...
- **静态建模**:主要包括类图、对象图和包图,它们描述了系统的静态结构,如类、对象、接口和它们之间的关系。 - **动态建模**:侧重于系统的动态行为,如顺序图、协作图、状态图和活动图,展示了系统中对象如何...
人工神经网络在这方面显示出其优越性,它能够通过学习逼近任意非线性映射,因此在非线性系统的建模与辨识中得到了广泛应用。尤其是静态多层前向神经网络,它具有逼近任意非线性映射的能力,是目前应用最为广泛的网络...
因此,必须利用UML的扩展机制对语义进行扩充,使其与ADL的语义相对应。UML的扩展机制包括但不限于对UML元素添加新的标记值、引入新的约束、建立新的关系类型等,以便能更精确地描述软件体系结构的元素。 总的来说,...
概念数据模型是指一组严格定义的模型元素的集合,这些模型元素精确地描述了系统的静态特性、动态特性以及完整性约束条件等。 概念数据模型的主要组成部分包括: 1. 实体(Entity):对应现实世界中可区别于其他...
这种方法不仅提高了工作流管理系统的易修改性和可扩充性,还能够更好地响应市场敏捷性的要求。未来的研究可以进一步探索如何在实践中更好地应用这种方法,以实现更高效、更灵活的工作流管理系统。
VRML语言的基本特性有两方面:实时3D着色引擎和可扩充性。实时3D着色引擎特性把VR的建模与实时访问明确隔离开, VRML可以有多个个方向的旋转及移动,实现和3D空间的超链接。 在虚拟旅游教学系统中,动态旅游模型的...
神经网络包括多层结构,其中最常见的是多层前向神经网络,尤其是具备反向传播(Back Propagation,BP)机制的网络,其训练过程通过误差反向传播来调整网络权重和偏置。MATLAB作为科研和工程计算领域广泛使用的编程...
这意味着设计师可以在建模的同时预览渲染效果,大大减少了工作流程中的繁琐步骤。同时,该插件还支持实时更新,当模型在Rhino中修改后,KeyShot会自动同步这些变化,保持设计的一致性。 在具体操作上,KeyShot的...
事物是UML模型中最基本的构成元素,是具有代表性的成分的抽象。关系把事物紧密联系在一起。图是事物和关系的可视化表示。 UML的事物可以分为四种:构件事物、行为事物、分组事物和注释事物。构件事物是UML模型的...
3. PID神经网络的价值:将静态神经元扩充到动态神经元、其实用性、对多变量系统良好的控制性能。 4. 基于PID神经网络的光照强度控制算法:通过优化PIDNN的连接权值,满足室内不同区域对灯光照明度的不同需求。 5. ...
4. 良好的交互性和可扩充性:数据库系统应该具备良好的交互性,能够方便用户使用,同时具备可扩充性,以适应产品设计的不断变化和技术更新。 在开发智能CAD设计系统时,可以通过面向对象的编程语言结合数据库技术,...
- **活动图**:展示了系统中关键业务流程,如选课流程、课程发布流程等。 - **状态图**:定义了系统中各个对象的状态及其转换条件,有助于理解系统的动态行为。 - **交互图**(包括顺序图和协作图):详细描述了...
文章指出,当前基于深度学习和深度摄像机的人体动作识别方法在特定场景下存在局限性,而该研究则定义了人体肢体角度空间,以增强对静态图像和快速变化场景中人体动作的识别能力。 BP(Back Propagation)回归神经...
数据库系统阶段是结构化数据的集中管理,具有高数据共享性、低数据冗余度、易扩充性和高度数据独立性。 数据模型部分介绍了数据模型的组成要素,包括数据结构、数据操作和数据的约束条件。数据结构是对系统静态特征...
* 三维施工平面图设计静态场景:提供施工现场场景布置功能,包括施工现场整体静态场景、导入CAD平面图、工地围墙和大门参数生成三维实体形式选自企业的LOGO图片用户方便扩充等功能。 * 施工动画制作动态过程:提供...
这一过程涉及到几何建模的知识,包括如何表达几何形状、如何建立模型与数据结构之间的关系,以及如何在异构CAD系统中实现信息的同步和互操作性。 同时,本文也讨论了如何在异构CAD系统间共享零件库信息。这不仅包括...
* 数据共享性高、冗余度低且易扩充:数据可以被多个用户、多个应用共享使用,减少数据冗余和存储空间。 * 数据独立性高:物理独立性和逻辑独立性使得用户的应用程序与数据库中数据的物理存储和逻辑结构独立。 * 数据...