ProcessEngineFactoryBean
对于Spring集成,配置和引擎bean将如下所示:
<bean id="processEngineConfiguration" class="org.flowable.spring.SpringProcessEngineConfiguration">
...
</bean>
<bean id="processEngine" class="org.flowable.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
交易
- 将DataSource传递给SpringProcessEngineConfiguration
- Flowable使用org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy内部,它包装传递的DataSource
- 目的:确保从DataSource和Spring事务中检索到的SQL连接能够很好地协同工作(意味着它不再需要代理的数据源自己在Spring的配)
- 确保在TransactionAwareDataSourceProxy自己声明Spring配置时,不要将它用于已经知道Spring事务的资源(例如,DataSourceTransactionManager和JPATransactionManager需要未代理的dataSource)
- Flowable使用org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy内部,它包装传递的DataSource
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="processEngineConfiguration" class="org.flowable.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="asyncExecutorActivate" value="false" />
</bean>
<bean id="processEngine" class="org.flowable.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
...
<beans>
...
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="userBean" class="org.flowable.spring.test.UserBean">
<property name="runtimeService" ref="runtimeService" />
</bean>
<bean id="printer" class="org.flowable.spring.test.Printer" />
</beans>
- 使用Spring支持的任何方式创建应用程序上下文
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"org/flowable/examples/spring/SpringTransactionIntegrationTest-context.xml");
- 使用repositoryService来部署这样的进程
RepositoryService repositoryService =
(RepositoryService) applicationContext.getBean("repositoryService");
String deploymentId = repositoryService
.createDeployment()
.addClasspathResource("org/flowable/spring/test/hello.bpmn20.xml")
.deploy()
.getId();
表达式
- 使用ProcessEngineFactoryBean时,BPMN进程中的所有表达式默认情况下也会看到所有Spring bean
- 要完全暴露NO bean,只需在SpringProcessEngineConfiguration上将空列表作为beans属性传递。如果未设置beans属性,则上下文中的所有Spring bean都可用。
<bean id="processEngineConfiguration" class="org.flowable.spring.SpringProcessEngineConfiguration">
...
<property name="beans">
<map>
<entry key="printer" value-ref="printer" />
</map>
</property>
</bean>
<bean id="printer" class="org.flowable.examples.spring.Printer" />
3.在表达式中使用公开的bean:例如,SpringTransactionIntegrationTest hello.bpmn20.xml显示如何使用UEL方法表达式调用Spring bean上的方法
<definitions id="definitions">
<process id="helloProcess">
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="print" />
<serviceTask id="print" flowable:expression="#{printer.printMessage()}" />
<sequenceFlow id="flow2" sourceRef="print" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
自动资源部署
- 在流程引擎配置中,您可以指定一组资源。创建流程引擎后,将扫描和部署所有这些资源
- 有过滤可以防止重复部署。仅当资源实际更改时,才会将新部署部署到Flowable DB
<bean id="processEngineConfiguration" class="org.flowable.spring.SpringProcessEngineConfiguration">
...
<property name="deploymentResources"
value="classpath*:/org/flowable/spring/test/autodeployment/autodeploy.*.bpmn20.xml" />
</bean>
<bean id="processEngine" class="org.flowable.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
- 默认情况下,上面的配置会将与过滤器匹配的所有资源分组到Flowable引擎的单个部署中
- 这些资源中只有一个流程定义发生了变化,则整个部署将被视为新部署
- 自定义部署的确定方式
- 在SpringProcessEngineConfiguration中指定其他属性deploymentMode(定义从与筛选器匹配的资源集确定部署的方式)
- default:将所有资源分组到单个部署中,并对该部署应用重复筛选
- single-resource:为每个单独的资源创建单独的部署,并对该部署应用重复过滤。这是用于单独部署每个流程定义的值,如果已更改,则仅创建新的流程定义版本
- resource-parent-folder:为共享同一父文件夹的资源创建单独的部署,并对该部署应用重复筛选。此值可用于为大多数资源创建单独的部署,但仍可以通过将它们放在共享文件夹中来对其进行分组
<bean id="processEngineConfiguration"
class="org.flowable.spring.SpringProcessEngineConfiguration">
...
<property name="deploymentResources" value="classpath*:/flowable/*.bpmn" />
<property name="deploymentMode" value="single-resource" />
</bean>
- 创建一个子类SpringProcessEngineConfiguration并覆盖该getAutoDeploymentStrategy(String deploymentMode)方法
单元测试
与Spring集成时,可以使用标准的Flowable测试工具轻松测试业务流程
JUnit 5测试
@ExtendWith(FlowableSpringExtension.class)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = SpringJunitJupiterTest.TestConfiguration.class)
public class MyBusinessProcessTest {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Test
@Deployment
void simpleProcessTest() {
runtimeService.startProcessInstanceByKey("simpleProcess");
Task task = taskService.createTaskQuery().singleResult();
assertEquals("My Task", task.getName());
taskService.complete(task.getId());
assertEquals(0, runtimeService.createProcessInstanceQuery().count());
}
}
网友评论