项目实践之工作流引擎基本文档!Activiti工作流框架中流程引擎API和服务详解 (2)

这个异常可以在任何时候被API抛出,特定方法抛出的特定的异常

/** * Called when the task is successfully executed. * @param taskId the id of the task to complete, cannot be null. * @throws ActivitiObjectNotFoundException when no task exists with the given id. */ void complete(String taskId);

当传入一个不存在的任务的id时,就会抛出异常.taskId不能为null,如果传入null,就会抛出ActivitiIllegalArgumentException

应该避免过多的异常继承,子类只用于特定的场合

流程引擎和API调用的其他场合不使用子类异常,抛出一个普通的ActivitiExceptions

ActivitiWrongDbException: 当Activiti引擎发现数据库版本号和引擎版本号不一致时抛出 ActivitiOptimisticLockingException: 对同一数据进行并发方法并出现乐观锁时抛出 ActivitiClassLoadingException: 当无法找到需要加载的类或在加载类时出现了错误-JavaDelegate,TaskListener ActivitiObjectNotFoundException: 当请求或操作的对应不存在时抛出 ActivitiIllegalArgumentException: 这个异常表示调用Activiti API时传入了一个非法的参数,可能是引擎配置中的非法值,或提供了一个非法值,或流程定义中使用的非法值 ActivitiTaskAlreadyClaimedException: 当任务已经被认领了,再调用taskService.claim(...)就会抛出 查询 API

在Activiti流程引擎中查询数据有两种方式:

查询API

原生查询

查询API: 查询API提供了完全类型安全的API,可以自定义添加查询条件和精确的排序条件,所有条件都以AND组合

List<Task> tasks = taskService.createTaskQuery() .taskAssignee("kermit") .processVariableValueEquals("orderId", "0815") .orderByDueDate().asc() .list();

原生查询:

需要更强大的查询时:使用OR条件或者能使用查询API实现的条件.

可以编写自己的SQL查询. 返回类型由你使用的查询对象决定,数据会映射到正确的对象上:任务,流程实例,执行..

查询作用在数据库上,必须使用数据库中定义的表名和列名,要了解内部数据结构

使用原生查询时,表名可以通过API获得,可以尽量减少对数据库的依赖

List<Task> tasks = taskService.createNativeTaskQuery() .sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) + " T WHERE T.NAME_ = #{taskName}") .parameter("taskName", "gonzoTask") .list(); long count = taskService.createNativeTaskQuery() .sql("SELECT count(*) FROM " + managementService.getTableName(Task.class) + " T1, " + managementService.getTableName(VariableInstanceEntity.class) + " V1 WHERE V1.TASK_ID_ = T1.ID_") .count(); 表达式

Activiti使用UEL处理表达式.UEL即统一表达式语言, 是EE6规范的一部分.为了在所有运行环境都支持最新UEL的所有功能,使用JUEL的修改版本

表达式可以用在很多场景下:

Java服务任务

执行监听器

任务监听器

条件流

虽然有两重表达式:值表达式和方法表达式, Activiti进行了抽象,所以两者可以同样使用在需要表达式的场景中

Value expression: 解析为值,默认

${myVar} ${myBean.myProperty}

所有流程变量都可以使用,所有spring bean(spring环境中)也可以使用在表达式中

Method expression: 调用一个方法,使用或不使用参数

${printer.print()} ${myBean.addNewOrder('orderName')} ${myBean.doSomething(myVar, execution)}

当调用一个无参数的方法时,记得在方法名后添加空的括号,以区分值表达式
传递的参数可以是字符串也可以是表达式,它们会被自动解析

这些表达式支持解析原始类型:

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() 方法

如果配置文件相同的话,对应的流程引擎会被静态缓存,就可以用于多个单元测试

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyffzw.html