Activiti 5.12用户指南之Activiti的Spring集成

 

     当然了,你也可以在没有Spring的环境中用Activiti,我们也已经提供了一些非常好的集成特点,在这一章节进行详解。
     
一、流程引擎实体工厂
     ProcessEngine能像普通Spring实体类一样被配置。一开始,我们讲解集成的重点就是org.activiti.spring.ProcessEngineFactoryBean这个类。这个类能通过配置流程引擎,并且创建流程引擎。这意味着用Spring属性的创建和配置是和之前文档中描述的一样的。对于Spring集成配置信息和引擎实体看起来会想是这样:
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    ...
</bean>
  
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
  <property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
  
二、事物
     我们会一步步的解释说明在发布包中Spring 例子中的SpringTransactionIntegrationTest。下面是Spring配置文件,这个配置文件我们会用在例子中。下面展示的包含了数据源,事物,流程引擎和Activiti 引擎服务。
     当DataSrourse传到SpringProcessEngineConfiguration,Activiti用一个内部的org.springframework.jdbc.datasourse.TransactionAwareDataSourseProxy包裹传过来的数据源。这样做,是为了确保SQL连接能从数据源取回。并且和Spring 事物一起运行的很好。这样你就不再需要在Spring配置中代理数据源,尽管配置文件中只允许向SpringProcessEngineConfiguration中传递TransactionAwareDataSourceProxy.
     在你自己的Spring的配置中,当你声明一个TransactionAwareDataSourceProxy的时候,要确保你没有用它作为Spring-transactions已经知道的资源。
     
<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="jobExecutorActivate" 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" />

...
 
     Spring配置文件包含的实体类和配置信息,在这个详细的例子中我们会用到:
     
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>
 
     首先,应用程序的上下文会以Spring任何方式被创建。在这个例子中,你能够用classpath下的XML资源文件去配置我们的Spring应用程序的上下文:
     
ClassPathXmlApplicationContext applicationContext = 
    new ClassPathXmlApplicationContext("org/activiti/examples/spring/SpringTransactionIntegrationTest-context.xml");
 
     或者,仅仅因为这是一个测试练习:
     
@ContextConfiguration("classpath:org/activiti/spring/test/transaction/SpringTransactionIntegrationTest-context.xml")
 
     然后,我们就能够获取到service实体类和他们的方法。processEngineFactoryBean会添加一个额外的拦截器到services中,在Activiti service方法里,The ProcessEngineFactoryBean will have added an extra interceptor to the services that applies Propagation.REQUIRED transaction semantics on the Activiti service methods.因此,例如,我们能用repositoryService去发布一个流程,像这样:
     
RepositoryService repositoryService = (RepositoryService) applicationContext.getBean("repositoryService");
String deploymentId = repositoryService
  .createDeployment()
  .addClasspathResource("org/activiti/spring/test/hello.bpmn20.xml")
  .deploy()
  .getId();
 
     其他的方式也一样会起作用。在这种情况下,Spring 事物会环绕在userBean.hello()方法并且Activiti service的方法也会加入到同一的事物中。
     
UserBean userBean = (UserBean) applicationContext.getBean("userBean");
userBean.hello();
 
     UserBean看起来像这样。记住,在上面的spring实体配置中,我们注入repositoryService到userBean中。     
     
public class UserBean {

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

  @Transactional
  public void hello() {
    // 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;
  }
}
 
三、表达式
     当用ProcessEngineFactoryBean的时候,默认的所有在BPMN进程中的表达式也会识别所有的Spring 实体。在表达式中去减少你想要暴漏的实体类或者即使不暴漏任何实体类通过用你配置的map,都是可能的。下面的例子,暴漏了一个单个的实体,用在“printer”的key下。为了不暴漏任何实体,仅仅需要传一个空的list作为“beans”属性配置在SpringProcessEngineConfiguration中.当不设置“beans”属性的时候,在上下文中的所有的Spring 实体都会被获取到。
     
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  ...
  <property name="beans">
    <map>
      <entry key="printer" value-ref="printer" />
    </map>
  </property>
</bean>
  
  <bean id="printer" class="org.activiti.examples.spring.Printer" />
 
     现在,暴漏的实体能被用在表达式中了:举个例子,hello.bpmn20.xml展示了一个Spring实体的一个方法怎么能被注入用一个UEL方法表达式中:     
     
<definitions id="definitions" ...>
  
  <process id="helloProcess">
  
    <startEvent id="start" />
    <sequenceFlow id="flow1" sourceRef="start" targetRef="print" />
    
    <serviceTask id="print" activiti:expression="#{printer.printMessage()}" />
    <sequenceFlow id="flow2" sourceRef="print" targetRef="end" />
    
    <endEvent id="end" />
    
  </process>

</definitions>
 
      Printer看起来是这样的:
     
public class Printer {

  public void printMessage() {
    System.out.println("hello world");
  }
}
 
     并且,Spring实体是这样配置的:     
     
<beans ...>
  ...

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

</beans>
 
四、自动资源部署     
     
     Spring整合也有一个特别的特点关于部署资源。在流程引擎配置中,你能指定一个资源的设置。当流程引擎创建的时候,他们所有的资源会被扫描和部署。会有适当的过滤阻止多个部署包。仅仅当资源文件确实已经改变了,这时会有一个新的部署包被部署到Activiti DB。在Spring容器重启的时候,这会对一些案例很有意义。
     这是一个例子:
     
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  ...
  <property name="deploymentResources" value="classpath*:/org/activiti/spring/test/autodeployment/autodeploy.*.bpmn20.xml" />
</bean>
  
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
  <property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
 
    
 
 
 
 
 
 
 
 

 

你可能感兴趣的:(Activiti)