This is the 10th day of my participation in Gwen Challenge

While you can definitely use Activiti without Spring, we’ve provided some very nice integration features, which are explained in this chapter.

ProcessEngineFactoryBean

The ProcessEngine can be configured as a normal Spring bean. The starting point of integration is a kind of org. Activiti. Spring. ProcessEngineFactoryBean. The bean takes the process engine configuration and creates the process engine. This means that the Spring properties are created and configured the same as documented in the configuration section. For Spring integration, the configuration and engine beans will look like this:

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">.</bean>

<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
  <property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
Copy the code

Please note that processEngineConfigurationbean now use org. Activiti. Spring. SpringProcessEngineConfiguration that class.

trading

We will explain SpringTransactionIntegrationTest gradually, in the Spring found in the sample distribution. Below is in this case, we use the Spring configuration file (you can SpringTransactionIntegrationTest – context. Find it in the XML). The sections shown below contain dataSource, transactionManager, processEngine, and Activiti Engine services.

When pass the DataSource SpringProcessEngineConfiguration (using the attribute “DataSource”), Activiti in org. Springframework. JDBC. The datasource. TransactionAwareDataSourceProxy internal use a, it wraps the datasource. This is done to ensure that SQL connections retrieved from the DataSource and Spring transactions work well together. This means that no longer need to their agent in the Spring configuration data sources, though it still allows to transfer a TransactionAwareDataSourceProxy SpringProcessEngineConfiguration. In this case, no additional packaging occurs.

Ensure TransactionAwareDataSourceProxy himself in a declaration in the Spring configuration, Don’t use it for already know Spring transaction resources (such as DataSourceTransactionManager and JPATransactionManager need not proxy data sources).

<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:activiti; 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.activiti.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.activiti.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" />.Copy the code

The rest of the Spring configuration file contains the beans and configuration we’ll use in this particular example:

<beans>.<tx:annotation-driven transaction-manager="transactionManager"/>

  <bean id="userBean" class="org.activiti.spring.test.UserBean">
    <property name="runtimeService" ref="runtimeService" />
  </bean>

  <bean id="printer" class="org.activiti.spring.test.Printer" />

</beans>
Copy the code

First, use any Spring methods to create the application context. In this example, you can configure our Spring application context using the classpath XML resource:

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
	"org/activiti/examples/spring/SpringTransactionIntegrationTest-context.xml");

Copy the code

Or because it’s a test:

@ContextConfiguration("classpath:org/activiti/spring/test/transaction/SpringTransactionIntegrationTest-context.xml")
Copy the code

We can then get the service beans and invoke their methods. The ProcessEngineFactoryBean will add an additional interceptor to the service, applying Propagation.REQUIRED transaction semantics on the Activiti service method. So, for example, we can use repositoryService to deploy a process like this:

RepositoryService repositoryService =
  (RepositoryService) applicationContext.getBean("repositoryService");
String deploymentId = repositoryService
  .createDeployment()
  .addClasspathResource("org/activiti/spring/test/hello.bpmn20.xml")
  .deploy()
  .getId();
Copy the code

Or the other way around. In this case, the Spring transaction will revolve around the userBean.hello() method, and the Activiti service method call will join the same transaction.

UserBean userBean = (UserBean) applicationContext.getBean("userBean");
userBean.hello();
Copy the code

The UserBean looks like this. Remember from the Spring Bean configuration above, we injected repositoryService into the userBean.

public class UserBean {

  /** injected by Spring */
  private RuntimeService runtimeService;

  @Transactional
  public void hello(a) {
    // here you can do transactional stuff in your domain model
    // and it will be combined in the same transaction as
    // the startProcessInstanceByKey to the Activiti RuntimeService
    runtimeService.startProcessInstanceByKey("helloProcess");
  }

  public void setRuntimeService(RuntimeService runtimeService) {
    this.runtimeService = runtimeService; }}Copy the code