ImageVerifierCode 换一换
格式:DOCX , 页数:28 ,大小:28.67KB ,
资源ID:7762890      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7762890.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(EOS工作流引擎原理doc.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

EOS工作流引擎原理doc.docx

1、EOS工作流引擎原理doc实用文案EOS 工作流引擎工作原理1.工作流基础知识2.EOS 工作流引擎工作原理本文是我在工作之余写的一点我对 EOS 工作流的了解,我的理解不一定全是对的,可能会与引擎的真正的面目有出入。所以只能提供给大家一点参考。2.1. EOS 工作流引擎核心调度算法EOS 工作流最重要的组成部分是它的核心调度算法,在我们没有深入研究它的工作原理之前我们认为它的工作原理是在工作项, 活动和流程实例对象上加了一些标志位来驱动流程的运转。 认为其引擎完全是个由数据库来驱动流程的引擎 (安徽二期的工作流平台好象就是以库表来驱动流程的运转) ,其实它是由事件来驱动流程运转的引擎,数据

2、库只是把引擎运转前后的状态持久化。在我近来在工作之余对其引擎的工作原理进行跟踪才弄明白在EOS 帮助文档上介绍的“事件驱动”的工作流引擎。2.1.1. EOS 工作流引擎的事件类型事件名称事件代码START_PROCESS:启动流程1001SCHEDULE_NEXT_ACTIVITY :由线程来启动下个活动实例1002BACKWORD_ACTIVITY :回退活动1003SUSPEND_PROCESS :流程挂起1004RESUME_PROCESS :启动挂起流程1005CHANGE_PROCESS_STATE :改变流程状态1006TERMINATE_PROCESS :终止流程1007ABO

3、RT_PROCESS :1008标准实用文案FINISH_PROCESS :结束流程1009PRESTART_ACTIVITY :重起流程2000START_ACTIVITY :启动活动实例2001RESTART_ACTIVITY :重起活动实例2002CHANGE_ACTIVITY_STATE :改变活动实例状态2003FINISH_ACTIVITY :结束活动实例2004TERMINATE_ACTIVITY:终止活动实例2005ABORT_ACTIVITY :2006SUSPEND_ACTIVITY:挂起活动实例2007RESUME_ACTIVITY:启动挂起的活动实例2008SUSPEN

4、D_WORKITEM:挂起工作项3001RESUME_WORKITEM:启动挂起工作项3002CHANGE_WORKITEM_STATE :改变工作项状态3003FINISH_WORKITEM:结束工作项3004TERMINATE_WORKTIEM :终止工作项3005ABORT_WORKTIEM:3006EXCEPTION_PROC_TIMEOUT :流程超时事件4002EXCEPTION_PROC_REMIND :流程临近超时事件4003EXCEPTION_ACT_TIMEOUT :活动超时事件4004EXCEPTION_ACT_REMIND :活动临近超时事件4005APPLICATIO

5、N_RETURN :5001以上的每个事件都是原子的不可分割的。其中一系列事件的集合通过EOS 引擎事件调标准实用文案度机制实现我们平时在工作中经常遇到的如启动流程,结束工作项等等。 (在事件类型类中EOS 定义了 29 种事件,但在事件工厂类中 EOS 定义了 26 种类型。)2.1.2. EOS 工作流事件调度机制EOS 事件的调度服务是在工作流引擎初始化时通过服务工厂类加载到内存中(ServiceFactory.initEventService() )。用户可以通过服务工厂类( ServiceFactory )取得JVM 的唯一事件服务实例进行事务调度。 所有的事件程序入口都是事件类 (

6、 EventService ),这个类其实是个接口, 其有两个实现类, 一个是单线程的实现类 SingleThreadEventService(在实现代码中其实不是单线程,而是单例的对象),一个是多线程的实现类MulThreadThreadSvc ,(其实现方式不在这里详细说明,多线程的类后面又跟了一大堆的线程池实现代码) ,在事件服务类中有一个属性类是 WFEventDisposer ,这个类包含了事件的注册,事件的发布,事件的注册是一个静态代码块实现的。注册了上节描述的 29 种事件,其实就是把相应的事件代码注册到相应的处理类,事件处理类共用 5 个( ProcessScheduler ,

7、 ActivityExecuter , ExceptionHandler , WorkItemHandler ,ApplicationHandler ),对应事件代码的前 5 个数字;共有事件的发布有两种,一种是正常发布,一种是无异常的发布(即在具体执行事件时关闭了异常处理) 。所谓的事件发布是给事件服务类传递一个事件对象( WFEvent 类),这个事件对象包含了事件类型,线程名,事件 ID ,流程定义 ID ,活动定义 ID ,活动实例 ID ,和工作项 ID 等等。以上简要的描述了事件模型, 下面来拿我们平时用的最多的一个构件: 结束工作项来详细跟踪它的事件处理。 结束工作项可能是最具有

8、代表性的一个流程动作, 因为在做这个时间后遍历了整个流程实例的流程:1,用户通过引擎的 API 调用 WorkItemManager类的 finishWorkItem方法,该方法通过服务工厂取得持久层的数据访问服务,并根据workitemID取得标准实用文案WFWorkItem 对象。做相关的判断后通过事件工厂类的createFinishWorkItemEvent 方法创建个事件代码为 3004 的事件对象( WFEvent )。然后通过服务工厂类取得事件服务类把该事件对象发布给事件处理服务。从此刻就开始了 EOS 事件调度服务的运转。2, 事件服务类(拿单线程事件服务类做例子)拿到这个事件类

9、后把该事件通过WFEventDisposer 发布该事件。具体的发布过程很简单,即判断该事件类型是否已注册,如果已经注册则取到改事件代码的注册类。该代码是3004 ,则应取 WorkItemHandler。然后调用 WorkItemHandler的 invoke ()方法,3,WorkItemHandler类 invoke ()中写到: if(event.getType()= 30004)finishWorkItem(event); 则找到该方法, 该方法开始做了相关的判断后做相关标志位的修改:置当前工作项的状态为12 ,然后判断当前活动是否结束。(大概的算法是取得已经结束的工作项和该活动总的

10、工作项,取得活动定义的多工作项是否启动。如果是多工作项则判断完成个数策略:是按百分比还是按操作员个数等等,做一系列的判断后得到应该结束的工作项,如果小于等于已经结束的工作项则该活动结束, 没有启动多工作项则相应的处理要简单点),如果该活动已完成,则调用事件服务的结束活动实例事件createFinishActivityEvent;如 果 没 有 结 束 则 判 断 工 作 项 启 动 的 策 略 是 “ at_the_same_time” 还 是“ one_by_one ”,如果是“ one_by_one ”则找本活动实例下的工作项状态为1的工作并启动它。4,结束活动实例是调用事件工厂的方法cr

11、eateFinishActivityEvent,新建一个事件代码为 2004 的事件。用 createFinishWorkItemEvent的方法发布该事件。到 ActivityExecuter类中找到 finishActivity ,该方法修改活动实例状态为7 ,标准实用文案填写活动结束时间。如果该活动注册了时限则取消活动时限的注册。如果该活动实例定义了结束活动的触发动作则触发该动作(通过 WFAppCaller 调用)。最 后 由 事 件 工 厂 产 生 一 个 事 件 代 码 为 1002 的createScheduleNextActivityEvent 事件。由事件服务发布事件。5,启

12、动下个活动实例的事件动作是事件工厂调用scheduleNextActivity方法,该方法通过流程定义找到下个环节的转移条件,并根据转移条件和分支模式(全部分支: AND ;多路分支: XOR ;单一分支: OR )生成一个环节定义列表。引擎首先把未启动的活动实例和挂起的活动实例找到,如果没有则生成一个活动实例。然后生成一个转移对象(WFTransition),最后把待启动的活动实例对象放到一个列表中。根据该列表中的活动定义的启动策略(直接启动,待激活,由规则逻辑指定)来启动活动实例;如果是直接启动活动实例则由事件工厂新建一个事件代码为2001 的事件 startActivity,如果待激活策

13、略则由事件工厂产生事件代码为2000的事件 preStartActivity。同样如果在流程定义中定义了创建活动实例触发的事件则触发该事件,scheduleNextActivity方法做了很多业务处理的事情,所以比较复杂。6,事件服务调用 startActivity方法,修改当前活动状态位为2,并向时限管理服务注册时限,然后通过活动执行类的帮助类分派工作项,分派工作项的过程是判断是否是多工作项,如果不是则按参与人员分派,如果是则判断多工作项的启动策略,启动工作项业务处理比较复杂,并没有相应的事件代码对应,在这里不详细介绍。以上的六个步骤完成了我们平时最常用的完成工作项的方法。综上所述应该能够对

14、EOS 工作流的事件调度机制有个清楚的认识,比如结束工作项的事件调度有标准实用文案3004-2004-1002-2001 这几种事件的触发。同样还有我们平时比较常用的启动流程实例方法首先是创建一个流程实例, 然后开始事件调度: 10001-10002-2001, 最后是分派工作项。OSWorkflow 里也有自己的调度机制,但在业务上要比 EOS简单的多,准确的讲OSWorkflow 只有两个概念: steps (步骤) 和 actions (动作)。一个简单的调度过程它可能从一个步骤流转到另外一个步骤(或者有时候还是停留在一样的步骤) 。它的调度其实就是一个类: AbstractWorkfl

15、ow ,这个类里面有两个方法: doAction 和transitionWorkflow 基本实现了所有的调度 (其实也不能算是调度, 只能算是状态的迁移) 。OSWorkflow 最大的优点是在执行调度过程中执行的一系列的 Function (在 SOA 里叫服务模型,在 EOS里叫展现逻辑),它在执行客户端的服务时的机制时还是比较复杂的,如果感兴趣在工作之余可以看一下。还有个最近比较流行的开源的引擎, JBpm ,我没看过这个,好象现在又整合到 JBOSS下去了,好象很复杂。2.2.时限管理服务2.2.1.时限的分类时限名称时限代码活动提醒时限ACT_PRE_REMIND活动执行时限ACT

16、_OVERTIME_REMIND流程提醒时限PROCESS_PRE_REMIND流程执行时限PROC_OVERTIME_REMIND时限类型有两种:一种是一次触发完成时限, 还有一种是循环触发 (譬如隔多长时间进标准实用文案行一次提醒)并可设置触发的次数。2.2.2. 时限计算器在工作流引擎启动时就启动一个 JVM 唯一实例的时限计算器,该类可以使用引擎默认的。也可以自己去实现一个自定义的计算方法, 在配置文件中注册要重写的类名即可。 引擎的时限计算器只有两个方法, 一个是计算结束时间, 还有一个是计算提醒时间。 其实是个静态类。2.2.3. 时限服务的启动在引擎中的时限服务有两个, 一个是引

17、擎启动的时候启动的时限服务, 该服务初始化了时限对象列表;一个是在引擎启动后启动的服务,该服务是对列表中的时限对象进行轮询,触发超时的时限对象对应的触发事件, 并移除该对象时限。 时限的线程处理用了大量的过程化程序的结构,在这里还是比较绕人的。2.2.4. 时限的注册和移除在流程引擎中的时限服务其实就是在维护一个时限对象的列表, 该列表记载了处于运行状态的活动的时限对象。在启动一个环节或启动一个流程时判断该活动或该流程的时限, 如果该活动或该流程定义了时限则向时限服务注册该时限 ;在 TimerManager 类中的注册方法的实现是调用时限服务类的 registeTimer 方法,往时限对象列

18、表( Vector )追加一条记录。在结束活动事件时或结束流程时如果是超时的操作则时限对象列表中没有该活动的时限对象, 因为该对象已被时限触发器触发并移除。 如果没有超时则要把这个向量列表中的那条时限对象给去掉。在 TimerManager 类中的注册移除方法的实现是调用时限服务类的unregisteTimer 方法,往时限对象列表( Vector )移除一条记录。2.2.5. 时限事件的触发标准实用文案时限的触发完全是后台的线程做的事情。 该线程对时限服务所维护的时限对象列表进行轮询,如果发现有超时的对象则触发已定义好的动作,该动作就是我们平时在 studio 中设的如果超时则干什么事的触发

19、动作。对时限的处理是通过 java.util.Timer 这个类来实现的。是通过新建一个时限任务(MyTimerT ask )让 Timer 来执行。 并向该类传递一个 OnceTimerHandler 对象实例。 该对 象 有 个 方 法 timerTrigged 就 是 到 了 预 定 时 限 时 触 发 的 方 法 。 该 方 法 首 先 调 用timerHandler 类的 handlerTimer 方法,即如果有触发事件的话就调用上节讨论的事件代码以 4 开头的事件。然后修改时限类的当前状态为 3 ,完成一次时限触发动作。3.流程同步服务流程同步服务是引擎自定义的一个对流程实例和流程

20、定义的锁的定义, 譬如在做指定下一个环节的参与人( WFAppointParticipantManager 中的 appointNextActParticipant方 法 ) 时 先 把 当 前 的 流 程 实 例 给 琐 住(ServiceFactory.getLockService().lockProcInstance )。然后在方法结束后再把流程实例的锁给释放( ServiceFactory.getLockService().releaseProcInstance )。在同步服务中定义了两种类型的锁,一种是流程定义锁,一种是流程实例琐(两个 list ),在加琐时检查改ID(流程实例 I

21、D 或流程定义 ID )是否已经在琐列表中,如果在则加琐。在加琐与解锁之间是通过一个线程来操作锁列表( waitingList )实现的。其实现方法大概是在加锁的时候向waitingList 添加一个锁对象,然后把线程 wait(); 在解锁的时候向 waitingList 减去一个锁对象,并把线程 notify() 。流程同步服务的实现方式还是比较复杂的。 尽管只用了七八个类。4.组织机构管理EOS 提供了一套自己的组织机构模型,我们在安徽服务保障三期中引用了该模型。该组织机构模型的服务会话面的实现是在配置文件中配置的,然后引擎采用 java 的反射机制标准实用文案加载配置类 (在引擎中有个

22、叫做 “服务定位器” 来实现, 该服务定位器和我们平时用的一样,只是它是从文件中读取服务定义, 隐藏了具体寻址细节) 。如果不用 EOS 提供的组织机构模型可以实现 WFOMService 接口,并实现里面的方法。估计 EOS 的原意是提供组织机构模型和引擎服务的松偶合,但在其引擎的实现上好象并没有做到。OMServiceImpl 类是引擎默认加载的组织机构模型会话面类。 该类定义了人员, 角色,机构等等, OMServiceImpl2 类包含岗位的组织机构模型(目前的引擎的还不支持,没有搞清楚 EOS 没有把岗位纳入组织机构模型中) ,但 EOS 提供的开源的组织机构模型中并不支持。5.审计

23、服务该服务记载了所有流程模板的变更和对流程实例的操作历史。 引擎共定义了 39 种审计类型,包括模板变更, 启动流程, 完成工作项等等。 由于审计的类型代码和引擎的事件代码,所以引擎在中间做了一层映射, 把事件代码和审计代码一一对应 (审计代码多于事件代码) 。在审计过程中其实是往审计表中加一条历史记录。6. 日志服务引擎的 LOG 服务很简单,和我们平时用的 LOG 差不多。在打日志的时候传入 JVM 唯一实例的日志上下文 WFLogContext ,在该类中定义了一条日志所需要的日志头,比如等级( level ),操作员( operator ),sql ( sql ),时间戳( times

24、tamp )等等。然后在具体打某一条日志的时候把日志头和日志内容拼装起来形成一条日志。引 擎 的 日 志 实 现 了 日 志 的 读 写 , 引 用 了 log4j 的 RollingFileAppender 和PatternLayout 。并提供了类似 AOP 的方法前后拦截打日志的服务(不知道方法前后的拦截日志是在代码中人工加上的还是由 AOP 代理自动加载的,因为采用了 AOP 时在编译的时候就把代码插入到要拦截的切入点中去) 。标准实用文案7.持久层服务引擎的持久层和 studio 里的持久层是采用一样的设计。大概是把数据库的字段和持久层的 XML 定义一一对应,没有采用像 hiber

25、nate 或者 EJB 的 CMP 或者 BMP 那样很复杂的 OR_mapping 。由 JDBC 驱动持久层在系统中显的很高效, 但采用数据库和持久层的 XML描述文件一一对应所以没有把关系数据的对象化做的很别致。 (没有深入的看过代码,可能我理解的不对) 。8.引擎的缓存工作流引擎的缓存是通过一个HashMap 来维护的。用有以下几类缓存:流程实例的缓存;活动实例的缓存;工作项的缓存;相关数据的缓存;相关数据 Dom 的缓存;流程属性数据的缓存, 以上几类的实例缓存个数是通过在配置文件中配置的, 还有一类流程模板的缓存是在引擎启动的时候就解析流程模板的 XML 文的定义(因为流程定义是通

26、过 XML 文来存储在数据库中) ,解析成流程定义对象并加载到内存中。8.1. 缓存的配置工作流缓存的配置是在 wfconfig.xml 文件中配置的。共有以下几种配置:false1000500010000标准实用文案100001000100010008.2. 缓存的实现在引擎启动的时候取得工作流配置信息, 如果允许使用缓存则初始化上面所述的六类缓存。在初始化的时候引擎默认缓存的存活时间为 0x1499700L 。缓存的大小为配置文件所配。这样则生成在 JVM 里的六个 Cache 类的实例。每个 Cache 都有一个 HashMap 的属性,这里面存储了要缓存的对象。 在 CacheFactory 类中又有一个 HashMap 对象属性, 这个对象存储的是 Cache 对象的集合。 就是上面所述的六个 Cache 类实例的集合。 普元的开发人员把该对象起名为 Caches 。那么在取某个活动实例时就先中缓存中读取,如果找到则直接返回,如果没有则从数据库中加载。引擎的缓存并不是直接把从数据库中取得的对象 put 到 map 中,而是做了一层优化,把从数据库中找到的对象封装成 CacheObject 对象,该对象有个链表( Linke

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1