Spring 集成
尽管你完全可以不使用 Spring 来使用 Flowable DMN,但我们在本章中介绍了一些非常好用的集成特性。
DmnEngineFactoryBean
DmnEngine 可以配置为一个常规的 Spring bean。集成的起点是 org.flowable.dmn.spring.DmnEngineFactoryBean 类。该 bean 接收一个 DMN 引擎配置并创建 DMN 引擎。这意味着 Spring 的属性创建与配置与配置章节中记录的相同。对于 Spring 集成,配置和引擎 bean 如下所示:
<bean id="dmnEngineConfiguration" class="org.flowable.dmn.spring.SpringDmnEngineConfiguration">
...
</bean>
<bean id="dmnEngine" class="org.flowable.dmn.spring.DmnEngineFactoryBean">
<property name="dmnEngineConfiguration" ref="dmnEngineConfiguration" />
</bean>
注意,dmnEngineConfiguration bean 现在使用 org.flowable.dmn.spring.SpringDmnEngineConfiguration 类。
自动资源部署
Spring 集成还具有一个用于部署资源的特殊功能。在 DMN 引擎配置中,你可以指定一组资源。创建 DMN 引擎时,将扫描并部署所有这些资源。其中设有过滤机制以防止重复部署。只有当资源实际发生变化时,才会向 Flowable DMN 数据库部署新的部署。这在很多用例中都很有用,例如 Spring 容器经常重启的场景(例如测试)。
下面是一个示例:
<bean id="dmnEngineConfiguration" class="org.flowable.spring.SpringDmnEngineConfiguration">
...
<property name="deploymentResources"
value="classpath*:/org/flowable/spring/test/autodeployment/autodeploy/decision*.dmn" />
</bean>
<bean id="dmnEngine" class="org.flowable.dmn.spring.DmnEngineFactoryBean">
<property name="dmnEngineConfiguration" ref="dmnEngineConfiguration" />
</bean>
默认情况下,上述配置会将所有匹配过滤条件的资源分组为一个部署,部署到 Flowable DMN 引擎。防止未更改资源重复部署的重复过滤应用于整个部署。在某些情况下,这可能不是你想要的。例如,如果你以这种方式部署一组 DMN 资源,而其中只有一个 DMN 定义发生了变化,整个部署将被视为新部署,该部署中的所有流程定义都会被重新部署,从而导致每个 DMN 定义都产生新版本,即使实际上只有一个发生了变化。
为了自定义部署的确定方式,你可以在 SpringDmnEngineConfiguration 中指定一个额外属性 deploymentMode。该属性定义了如何从匹配过滤条件的资源集合中确定部署。该属性默认支持以下三个值:
- default:将所有资源分组为一个部署,并对该部署应用重复过滤。这是默认值;如果你未指定值,将使用该值。
- single-resource:为每个单独的资源创建单独的部署,并对该部署应用重复过滤。使用该值可以让每个 DMN 定义单独部署,并且仅在 DMN 定义发生变化时才创建新版本。
- resource-parent-folder:为共享同一父文件夹的资源创建单独的部署,并对该部署应用重复过滤。使用该值可以为大多数资源创建单独的部署,同时仍能通过将某些资源放在共享文件夹中来对它们分组。下面是为 deploymentMode 指定 single-resource 配置的示例:
<bean id="dmnEngineConfiguration"
class="org.flowable.dmn.spring.SpringDmnEngineConfiguration">
...
<property name="deploymentResources" value="classpath*:/flowable/*.dmn" />
<property name="deploymentMode" value="single-resource" />
</bean>
除了为 deploymentMode 使用上面列出的值之外,你可能还希望自定义确定部署的行为。如果是这样,你可以创建 SpringDmnEngineConfiguration 的子类并重写 getAutoDeploymentStrategy(String deploymentMode) 方法。该方法确定对于 deploymentMode 配置的某个值使用哪种部署策略。
单元测试
与 Spring 集成时,可以使用标准的 Flowable 测试设施 非常轻松地测试决策。以下示例展示 了在典型的基于 Spring 的 JUnit Jupiter 测试中如何测试决策:
JUnit Jupiter 测试。
@ExtendWith(FlowableDmnSpringExtension.class)
@SpringJUnitConfig(DmnSpringJunitJupiterTest.TestConfiguration.class)
public class SpringJunit4Test {
@Autowired
private DmnEngine dmnEngine;
@Autowired
private DmnRuleService ruleService;
@Test
@DmnDeploymentAnnotation
public void simpleDecisionTest() {
Map<String, Object> executionResult = ruleService.createExecuteDecisionBuilder()
.decisionKey("extensionUsage")
.variable("inputVariable1", 2)
.variable("inputVariable2", "test2")
.executeWithSingleResult();
Assertions.assertThat(executionResult).containsEntry("output1", "test1");
}
}