项目实践之工作流引擎基本文档!Activiti 工作流框架中流程引擎 API 和服务详解
流程引擎的 API 和服务
流程引擎 API(ProcessEngine API)是与 Activiti 打交道的最常用方式
Activiti 从 ProcessEngine 开始.在 ProcessEngine 中,可以获得很多包括工作流或者 BPM 方法的服务
ProcessEngine 和服务类都是线程安全的.可以在整个服务器中仅保持它们的一个引用就可以
异常策略
Activiti 中的基础异常为 org.activiti.engine.ActivitiException, 一个非检查异常
这个异常可以在任何时候被 API 抛出,特定方法抛出的特定的异常
当传入一个不存在的任务的 id 时,就会抛出异常.taskId 不能为 null,如果传入 null,就会抛出 ActivitiIllegalArgumentException
应该避免过多的异常继承,子类只用于特定的场合
流程引擎和 API 调用的其他场合不使用子类异常,抛出一个普通的 ActivitiExceptions
查询 API
在 Activiti 流程引擎中查询数据有两种方式:
查询 API
原生查询
查询 API: 查询 API 提供了完全类型安全的 API,可以自定义添加查询条件和精确的排序条件,所有条件都以 AND 组合
原生查询:
需要更强大的查询时:使用 OR 条件或者能使用查询 API 实现的条件.
可以编写自己的 SQL 查询. 返回类型由你使用的查询对象决定,数据会映射到正确的对象上:任务,流程实例,执行..
查询作用在数据库上,必须使用数据库中定义的表名和列名,要了解内部数据结构
使用原生查询时,表名可以通过 API 获得,可以尽量减少对数据库的依赖
表达式
Activiti 使用 UEL 处理表达式.UEL 即统一表达式语言, 是 EE6 规范的一部分.为了在所有运行环境都支持最新 UEL 的所有功能,使用 JUEL 的修改版本
表达式可以用在很多场景下:
Java 服务任务
执行监听器
任务监听器
条件流
虽然有两重表达式:值表达式和方法表达式, Activiti 进行了抽象,所以两者可以同样使用在需要表达式的场景中
Value expression: 解析为值,默认
所有流程变量都可以使用,所有 spring bean(spring 环境中)也可以使用在表达式中
Method expression: 调用一个方法,使用或不使用参数
当调用一个无参数的方法时,记得在方法名后添加空的括号,以区分值表达式传递的参数可以是字符串也可以是表达式,它们会被自动解析
这些表达式支持解析原始类型:
bean
list
数组
map
包括比较
在流程实例中,表达式中可以使用一些默认对象:
execution: DelegateExecution,提供外出执行的额外信息
task: DelegateTask,提供当前任务的额外信息 ,只对任务监听器的表达式有效
authenticatedUserId: 当前登录的用户 id.如果没有用户登录,这个变量就不可用
单元测试
业务流程是软件项目的一部分,它也应该和普通的业务流程一样进行测试:使用单元测试
因为 Activiti 是一个嵌入式的 java 引擎,所以为业务流程编写单元测试和写普通单元测试完全一样
Activiti 支持 JUnit 3 和 4 进行单元测试
使用 JUnit 3 时, 必须集成 org.activiti.engine.test.ActivitiTestCase. 它通过保护的成员变量提供 ProcessEngine 和服务,
在测试的 setup()中,默认会使用 classpath 下的 activiti.cfg.xml 初始化流程引擎
要使用不同的配置文件,可以重写 getConfigurationResource() 方法
如果配置文件相同的话,对应的流程引擎会被静态缓存,就可以用于多个单元测试
继承了 ActivitiTestCase, 可以在测试方法上使用 org.activiti.engine.test.Deployment 注解.测试执行前,与测试类在同一个包下的,格式为 testClassName.testMethod.bpmn20.xml 的资源文件,会被部署.测试结束后,发布包也会被删除,包括所有相关的流程实例,任务...Deployment 注解也可以直接设置资源的位置
要想在使用 JUnit 4 编写单元测试时获得同样的功能
可以使用 org.activiti.engine.test.ActivitiRule. 通过它,可以通过 getter 方法获得流程引擎和各种服务
使用这个 Rule 也会启用 org.activiti.engine.test.Deployment 注解
它会在 classpath 下查找默认的配置文件,如果配置文件相同的话,对应的流程引擎会被静态缓存,就可以用于多个单元测试
调试单元测试
使用内存数据库 H2 进行单元测试,在调试环境监视 Activiti 的数据库:
在单元测试里设置了一个断点:
用调试模式运行单元测试,右击单元测试,选择[运行为]和[单元测试],测试会停在我们的断点上, 然后我们就可以监视测试的变量,它们显示在调试面板里
要监视 Activiti 的数据,打开[显示]窗口(如果找不到,打开[窗口]-[显示视图]-[其他],选择[显示]并点击[代码已完成],org.h2.tools.Server.createWebServer("-web").start()
选择你点击的行,右击.然后选择[显示]
打开一个浏览器,输入 http://localhost:8082, 输入内存数据库的 JDBC URL(默认为 jdbc:h2:mem:activiti),点击连接按钮
可以看到 Activiti 的数据,通过它们可以了解单元测试时,如何以及为什么这样运行的
Web 中的流程引擎
ProcessEngine 是线程安全的,可以在多线程下共享
在 web 应用中, 意味着可以在容器启动时创建流程引擎, 在容器关闭时关闭流程引擎
编写一个 ServletContextListener 在普通的 Servlet 环境下初始化和销毁流程引擎:
contextInitialized 方法会执行 ProcessEngines.init() 这会查找 classpath 下的 activiti.cfg.xml 文件,根据配置文件创建一个 ProcessEngine(比如,多个 jar 中都包含配置文件)如果 classpath 中包含多个配置文件,确认它们有不同的名字
需要使用流程引擎时,可以通过
或
ContextListener 中的 contextDestroyed 方法会执行 ProcessEngines.destroy().这会关闭所有初始化的流程引擎
版权声明: 本文为 InfoQ 作者【攻城狮Chova】的原创文章。
原文链接:【http://xie.infoq.cn/article/44389d7a3e83be9be7e9a2ba2】。文章转载请联系作者。
评论