Activiti工作流中的集成CDI

  • Activiti工作流集成CDI简介
  • 设置activiti-cdi
  • 查找流程引擎
  • 配置Process Engine
  • 发布流程
  • 基于CDI环境的流程执行
  • 与流程实例进行关联交互
  • 声明式流程控制
  • 在流程中引用bean
  • 使用@BusinessProcessScoped beans
  • 注入流程变量
  • 接收流程事件
  • Activiti CDI中的更多功能

打开网易新闻 查看更多图片

Activiti工作流集成CDI简介

  • activiti-cdi模块提供activiti的可配置型和cdi扩展
  • activiti-cdi的特性:支持 @BusinessProcessScoped beans, 绑定到流程实例的cdi bean流程为cdi bean支持自定义EL处理器使用注解为流程实例提供声明式控制Activiti可以挂接在cdi事件总线上支持Java EEJava SE, 支持Spring支持单元测试
  • 要在maven项目中使用activiti-cdi,需要添加
  • activiti-cdi 5.6以上的版本会自动加入activiti-entinspring

设置activiti-cdi

  • Activiti cdi可以安装在不同环境中

查找流程引擎

  • cdi扩展需要访问到ProcessEngine, 为了实现此功能:使用org.activiti.cdi.spi.ProcessEngineLookup接口在运行期间进行查找cdi模块使用默认的名为org.activiti.cdi.impl.LocalProcessEngineLookup的实现,使用ProcessEngines这个工具类来查找ProcessEngine默认配置下,使用ProcessEngines#NAME_DEFAULT来查找**ProcessEngine.**这个类可能是使用自定义名称的子类注意: 需要把activiti.cfg.xml放在classpath
  • Activiti cdi使用java.util.ServiceLoader SPI处理org.activiti.cdi.spi.ProcessEngineLookup的实例为了提供接口的自定义实现,需要创建一个文本文件,名为META-INF/services/org.activiti.cdi.spi.ProcessEngineLookup, 在文件中需要指定实现的全类名如果你没有提供自定义的org.activiti.cdi.spi.ProcessEngineLookup实现,activiti会使用默认的LocalProcessEngineLookup实现,需要做的就是把activiti.cfg.xml放到classpath

配置Process Engine

  • 实际的配置依赖于选用的ProcessEngineLookup策略
  • 在这里主要结合LocalProcessEngineLookup讨论可用的配置,要求在classpath下提供一个springactiviti.cfg.xml
  • Activiti提供了不同的ProcessEngineConfiguration实现,主要是依赖实际使用的事务管理策略
  • activiti-cdi模块对事务的要求不严格,意味着任何事务管理策略都可以使用,即便是spring事务抽象层
  • cdi模块提供两种自定义ProcessEngineConfiguration实现:org.activiti.cdi.CdiJtaProcessEngineConfiguration: activiti的JtaProcessEngineConfiguration的子类,用于在activiti使用JTA管理的事务环境org.activiti.cdi.CdiStandaloneProcessEngineConfiguration: activiti的StandaloneProcessEngineConfiguration的子类,用于在activiti使用简单JDBC事务环
  • 注意: 上面的配置要引入spring-context模块依赖

发布流程

  • 可以使用标准的activiti-api发布流程-RepositoryService
  • activiti-cdi也提供了自动发布classpathprocesses.xml中列出的流程的方式

基于CDI环境的流程执行

  • BPMN业务流程通常是一个长时间运行的操作,包含了用户和系统任务的操作
  • 运行过程中,流程会分成多个单独的工作单元,由用户和应用逻辑执行
  • activiti-cdi中,流程实例可以分配到cdi环境中,关联展现成一个工作单元:这是非常有用的,如果工作单元太复杂:比如如果实现的用户任务是不同形式的复杂顺序,可以在这个操作中保持non-process-scoped状态默认配置下,流程实例分配到broadest激活环境,就会启动交互,如果交互环境没有激活,就会返回到请求中

与流程实例进行关联交互

  • 处理 @BusinessProcessScoped beans, 或注入流程变量时,实现了激活的cdi环境与流程实例的关联
  • Activiti-cdi提供了org.activiti.cdi.BusinessProcess bean来控制关联:startProcessByXx(…): 对应activiti的RuntimeService中的相关方法,允许启动和随后相关联的业务流程resumeProcessById(String processInstanceId): 允许通过提供的Id来关联流程实例resumeTaskById(String taskId): 允许通过提供的Id来关联任务,也可以扩展关联流程实例
  • 一个工作单元完成后 ,completeTask() 方法可以调用来解除流程实例和会话或请求的关联.这会通知activiti当前任务已经完成,并让流程实例继续执行
  • BusinessProcess bean@Named bean, 意思是导出的方法可以通过表达式语言调用:比如在JSF页面中.下面的JSF 2 代码启动一个新的交互,分配给一个用户任务实例,Id作为一个请求参数传递

声明式流程控制

  • Activiti-cdi允许通过注解声明启动流程实例和完成任务
  • @org.activiti.cdi.annotation.StartProcess注解允许通过keyname启动流程实例.流程实例会在注解的方法返回之后启动

根据activiti的配置,注解方法的代码和启动流程实例会在同一个事务中执行 .@org.activiti.cdi.annotation.CompleteTask事务的使用方式相同

  • @CompleteTask注解可以结束当前会话.默认行为会在activiti返回后结束会话.可以禁用结束会话的功能

在流程中引用bean

  • Activiti-cdi使用自定义解析器把CDI bean暴露到activiti El中,可以在流程中引用这些bean

使用@BusinessProcessScoped beans

  • 使用activiti-cdi,bean的生命周期可以绑定到流程实例上:可以提供一个自定义的环境实现,命名为BusinessProcessContext.BusinessProcessScoped bean的实例会作为流程变量保存到当前流程实例中BusinessProcessScoped bean需要是**PassivationCapable,**比如序列化
  • 使用流程作用域bean的示例如下

有时,需要使用流程作用域bean,没有与流程实例关联

  • 比如启动流程之前.如果当前流程实例没有激活 ,BusinessProcessScoped bean实例会暂时保存在局部作用域里:会话请求依赖环境
  • 如果作用域后来与业务流程实例关联了,bean实例会刷新到流程实例里

注入流程变量

  • 流程变量可以实现用于注入
  • Activiti-CDI支持以下注入流程变量的方式:@BusinessProcessScoped使用 @Inject [附加修饰] 类型 属性名实现类型安全的流程变量的注入使用**@ProcessVariable(name)**修饰符实现对类型不安全的流程变量的注入

为了通过EL引用流程变量, 可以使用如下方式:@Named @BusinessProcessScoped beans可以直接引用其他流程变量可以使用ProcessVariables bean来使用

接收流程事件

  • Activiti可以挂在CDI的事件总线上,就可以使用标准CDI事件机制来监听流程事件
  • 为了启用activiti的CDI事件支持,需要在配置中启用对应的解析监听器

这样activiti就配置成了使用CDI事件总线发布事件

  • CDI bean中处理事件的方式:使用**@Observes**注解声明特定的事件监听器事件监听是类型安全的流程事件类型是org.activiti.cdi.BusinessProcessEvent
  • 一个简单事件监听方法示例

监听器可以监听所有事件.如果想限制监听器接收的事件类型,可以添加修饰注解:

  • @BusinessProcess: 限制指定流程定义的事件@Observes @BusinessProcess(“billingProcess”)
  • @StartActivity: 限制指定进入环节的事件@Observes @StartActivity(“shipGoods”)
  • @EndActivity: 限制指定结束环节的事件@Observes @EndActivity(“shipGoods”)
  • @TakeTransition: 限制指定连线的事件
  • 修饰命名可以自由组合:为了接收shipmentProcess流程中所有离开shipGoods环节的事件

打开网易新闻 查看更多图片

  • 默认配置下,事件监听器是同步调用,并在同一个事务环境中
  • CDI事务性监听器可以控制监听器什么时候处理事件
  • 可以保证监听器只在事件中的事务成功之后才处理

Activiti CDI中的更多功能

  • 流程引擎和服务都可以注入: Inject ProcessEngine,RepositoryService,TaskService,…
  • 当前流程实例和任务可以注入: @Inject ProcessInstance, Task
  • 当前业务标识可以注入: @Inject @BusinessKey String businessKey
  • 当前流程实例id可以注入: @Inject @ProcessInstanceId String pid