1、表达式

流动性使用UEL进行表达式解析。UEL代表统一表达式语言(Unified Expression Language),是EE6规范的一部分。

表达式可用于,例如,Java服务任务,执行监听器,任务监听器和条件序列流。虽然有两种类型的表达式,值表达式和方法表达式,但是Flowable将这种表达式抽象出来,所以它们都可以用在需要的地方expression。

值表达式:解析为一个值。默认情况下,所有的过程变量都可以使用。此外,所有春豆(如果使用Spring)都可以在表达式中使用。一
些例子:

$ {myVar的}
$ {} myBean.myProperty

方法表达式:调用带或不带参数的方法。当调用一个没有参数的方法时,一定要在方法名之后加上空的圆括号(因为这和表达式区分一个值表达式)。传递的参数可以是字面值或自己解析的表达式。例子:

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

请注意,这些表达式支持解析原语(包括比较它们),bean,列表,数组和地图。

在所有的过程变量之上,有几个可以在表达式中使用的默认对象:

  • execution:DelegateExecution持有关于持续执行的附加信息。
  • task:DelegateTask持有关于当前任务的附加信息。注意:只适用于任务监听器评估的表达式。
  • authenticatedUserId:当前通过身份验证的用户的ID。如果没有用户通过身份验证,该变量不可用。

2、单元测试

业务流程是软件项目不可分割的一部分,应该按照与正常应用程序逻辑测试相同的方式进行测试:使用单元测试。由于Flowable是一个可嵌入的Java引擎,编写单元测试业务流程就像编写常规的单元测试一样简单。

流动支持JUnit版本3和4的单元测试风格。在JUnit 3风格中,org.flowable.engine.test.FlowableTestCase必须扩展。这将通过受保护的成
员字段使ProcessEngine和服务可用。在setup()测试中,processEngine将默认使用flowable.cfg.xml类路径上的资源进行初始化。要指定不同的配置文件,请覆盖getConfigurationResource()方法。当配置资源相同时,流程引擎会静态缓存在多个单元测试中。

通过扩展FlowableTestCase,您可以使用批注测试方法org.flowable.engine.test.Deployment。在测试运行之前testClassName.testMethod.bpmn20.xml,将部署与测试类相同包中的表单资源文件。在测试结束时,部署将被删除,包括所有相关的流程实例,任务等等。该Deployment注释还支持明确设置的资源位置。查看课程本身以获取更多信息。

考虑到所有这些,JUnit 3风格测试如下所示。

public class MyBusinessProcessTest extends FlowableTestCase {
@Deployment
public void testSimpleProcess() {
runtimeService.startProcessInstanceByKey("simpleProcess");
Task task = taskService.createTaskQuery().singleResult();
assertEquals("My Task", task.getName());
taskService.complete(task.getId());
assertEquals(0, runtimeService.createProcessInstanceQuery().count());
}
}

为了在使用JUnit 4编写单元测试时获得相同的功能,org.flowable.engine.test.FlowableRule必须使用规则。通过这个规则,流程引擎和服务可以通过获取者获得。就像FlowableTestCase(见上)一样,包括这个Rule可以使用org.flowable.engine.test.Deployment注释(参见上面的使用和配置说明),它将在类路径中查找默认的配置文件。当使用相同的配置资源时,流程引擎会静态缓存在多个单元测试中。

下面的代码片段显示了使用JUnit 4风格的测试和使用的例子FlowableRule。

public class MyBusinessProcessTest {
@Rule
public FlowableRule FlowableRule = new FlowableRule();
@Test
@Deployment
public void ruleUsageExample() {
RuntimeService runtimeService = FlowableRule.getRuntimeService();
runtimeService.startProcessInstanceByKey("ruleUsage");
TaskService taskService = FlowableRule.getTaskService();
Task task = taskService.createTaskQuery().singleResult();
assertEquals("My Task", task.getName());
taskService.complete(task.getId());
assertEquals(0, runtimeService.createProcessInstanceQuery().count());
}
}

3、调试单元测试

当使用内存H2数据库进行单元测试时,以下说明允许您在调试会话期间轻松检查Flowable数据库中的数据。这里的屏幕截图是在Eclipse中进行的,但是其他IDE的机制应该是相似的。

假设我们在单元测试的某处放置了一个断点(在Eclipse中,这是通过双击代码旁边的左边框来完成的):

flowable如何写入business_key flowable官方文档_java


如果我们现在在调试模式下运行单元测试(在测试类中右键单击,选择Run as,然后选择JUnit test),测试执行在我们的断点处停止,现在我们可以在右边看到我们测试的变量上面板。

flowable如何写入business_key flowable官方文档_流程自动化_02


要检查可流动数据,打开“显示”窗口(如果此窗口不在此处,请打开窗口→显示视图→其他并选择显示),然后键入(代码完成可用)org.h2.tools.Server.createWebServer("-web").start()

flowable如何写入business_key flowable官方文档_BPM_03


选择你刚刚输入的行,然后右键单击它。现在选择显示(或执行快捷键而不是右键单击)

flowable如何写入business_key flowable官方文档_流程自动化_04


现在用浏览器输入http:// localhost:8082,然后将JDBC URL填入内存数据库(默认情况下是这样jdbc:h2:mem:flowable),然后点击连接按钮。

flowable如何写入business_key flowable官方文档_工作流_05


您现在可以看到Flowable数据并用它来了解单元测试如何以及为什么以某种方式执行您的过程。

flowable如何写入business_key flowable官方文档_工作流_06

4、Web应用程序中的流程引擎

ProcessEngine是一个线程安全的类,可以很容易地在多个线程之间共享。在Web应用程序中,这意味着可以在容器启动时创建一次流程引擎,并在容器停机时关闭引擎。

下面的代码片断展示了如何编写一个简单的ServletContextListener在简单的Servlet环境中初始化和销毁流程引擎:

public class ProcessEnginesServletContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
ProcessEngines.init();
} p
ublic void contextDestroyed(ServletContextEvent servletContextEvent) {
ProcessEngines.destroy();
}
}

该contextInitialized方法将委托给ProcessEngines.init()。这将flowable.cfg.xml在类路径中查找资源文件,并ProcessEngine为给定配置(例如,具有配置文件的多个JAR)创建一个。如果在类路径中有多个这样的资源文件,请确保它们都有不同的名称。当需要流程引擎时,可以使用以下方式获取流程引擎:

ProcessEngines.getDefaultProcessEngine()

要么

ProcessEngines.getProcessEngine("myName");

当然,也可以使用任何创建流程引擎的变体。在contextDestroyed上下文监听代表们的方法ProcessEngines.destroy()。这将正确关闭所有初始化的流程引擎。