读书人

Activiti 5.3:配备与Spring整合

发布时间: 2012-10-17 10:25:47 作者: rapoo

Activiti 5.3:配置与Spring整合


Activiti 5.3与Spring整合也比较简单,其基本思想就是,通过Spring的IOC容器来管理Activiti的流程引擎实例以及相关服务,可见,主要是基于Activiti在与Spring整合上努力上,做好配置即可。这里基于前面的<receiveTask>的例子来进行,可以参考:Activiti 5.3:流程活动自动与手工触发执行,简单的流程,如图所示:

Activiti 5.3:配备与Spring整合

Activiti 5.3与Spring整合,默认使用的配置文件为activiti-context.xml,当然可以在实际使用的时候覆盖掉默认的配置,或者增加自己的其他的Spring的配置。

我们也命名为activiti-context.xml,内容(安装Activiti 5.3的时候,实例工程中已经附带)如下所示:

[java] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:tx="http://www.springframework.org/schema/tx"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
  8. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
  9. <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
  10. <property name="driverClass" value="org.h2.Driver" />
  11. <property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
  12. <property name="username" value="sa" />
  13. <property name="password" value="" />
  14. </bean>
  15. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  16. <property name="dataSource" ref="dataSource" />
  17. </bean>
  18. <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  19. <property name="dataSource" ref="dataSource" />
  20. <property name="transactionManager" ref="transactionManager" />
  21. <property name="databaseSchemaUpdate" value="true" />
  22. <property name="mailServerHost" value="localhost" />
  23. <property name="mailServerPort" value="5025" />
  24. <property name="jpaHandleTransaction" value="true" />
  25. <property name="jpaCloseEntityManager" value="true" />
  26. <property name="jobExecutorActivate" value="false" />
  27. </bean>
  28. <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
  29. <property name="processEngineConfiguration" ref="processEngineConfiguration" />
  30. </bean>
  31. <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
  32. <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
  33. <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
  34. <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
  35. <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
  36. </beans>

这里面,我把Activiti 5.3默认工程中有关JPA的部分配置删除了,其实通过这个就可以初始化Activiti引擎实例。为了测试方便,将获取服务的实现抽象出来,同时使用Spring自带的与JUnit4集成的工具(AbstractTransactionalJUnit4SpringContextTests)。我们的实现类为AbstractSpringTest,代码如下所示:

[java] view plaincopy
  1. package org.shirdrn.workflow.activiti;
  2. import java.util.logging.Logger;
  3. import org.activiti.engine.HistoryService;
  4. import org.activiti.engine.ManagementService;
  5. import org.activiti.engine.ProcessEngine;
  6. import org.activiti.engine.RepositoryService;
  7. import org.activiti.engine.RuntimeService;
  8. import org.activiti.engine.TaskService;
  9. import org.junit.After;
  10. import org.junit.Before;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.test.context.ContextConfiguration;
  13. import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
  14. /**
  15. * @author shirdrn
  16. */
  17. @ContextConfiguration("classpath:activiti-context.xml")
  18. public abstract class AbstractSpringTest extends AbstractTransactionalJUnit4SpringContextTests {
  19. @SuppressWarnings("unused")
  20. private final Logger log = Logger.getLogger(AbstractSpringTest.class.getName());
  21. @SuppressWarnings("unused")
  22. @Autowired
  23. private ProcessEngine processEngine;
  24. @Autowired
  25. protected RepositoryService repositoryService;
  26. @Autowired
  27. protected RuntimeService runtimeService;
  28. @Autowired
  29. protected TaskService taskService;
  30. @Autowired
  31. protected HistoryService historyService;
  32. @Autowired
  33. protected ManagementService managementService;
  34. protected String deploymentId;
  35. public AbstractSpringTest() {
  36. super();
  37. }
  38. @Before
  39. public void initialize() throws Exception {
  40. beforeTest();
  41. }
  42. @After
  43. public void clean() throws Exception {
  44. afterTest();
  45. }
  46. protected abstract void beforeTest() throws Exception;
  47. protected abstract void afterTest() throws Exception;
  48. }

上面,将classpath:activiti-context.xml在测试的时候进行加载,这样,在测试的子类中,只需要将其他的相关Spring配置单独加载即可,业务配置与流程配置分开,便于维护。

具体测试用例,这里实现了一个简单的Spring Bean,配置文件为mySpringContext.xml,如下所示:

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
  7. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
  8. <bean id="mySpringBean" class="org.shirdrn.workflow.activiti.spring.MySpringBean">
  9. <property name="id" value="65536" />
  10. <property name="name" value="shirdrn" />
  11. </bean>
  12. </beans>

Spring Bean的实现,代码如下所示:

[java] view plaincopy
  1. package org.shirdrn.workflow.activiti.spring;
  2. import java.io.Serializable;
  3. public class MySpringBean implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. private Integer id;
  6. private String name;
  7. public Integer getId() {
  8. return id;
  9. }
  10. public void setId(Integer id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. @Override
  20. public String toString() {
  21. return "MySpringBean[id="+ id + ",name=" + name + "]";
  22. }
  23. }

下面,看看我们具体的测试用例,实现代码如下所示:

[java] view plaincopy
  1. package org.shirdrn.workflow.activiti.spring;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. import org.activiti.engine.repository.Deployment;
  6. import org.activiti.engine.runtime.Execution;
  7. import org.activiti.engine.runtime.ProcessInstance;
  8. import org.junit.Test;
  9. import org.shirdrn.workflow.activiti.AbstractSpringTest;
  10. import org.shirdrn.workflow.activiti.subprocess.Merchant;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.test.context.ContextConfiguration;
  13. /**
  14. * @author shirdrn
  15. */
  16. @ContextConfiguration({
  17. "classpath:org/shirdrn/workflow/activiti/spring/mySpringContext.xml"})
  18. public class ActivitiWithSpringTest extends AbstractSpringTest {
  19. @Autowired
  20. private MySpringBean mySpringBean;
  21. @Override
  22. protected void beforeTest() throws Exception {
  23. Deployment deployment = repositoryService
  24. .createDeployment()
  25. .addClasspathResource(
  26. "diagrams/Task.ReceiveTask.bpmn20.xml")
  27. .deploy();
  28. deploymentId = deployment.getId();
  29. }
  30. @Override
  31. protected void afterTest() throws Exception {
  32. repositoryService.deleteDeployment(deploymentId, true);
  33. }
  34. @Test
  35. public void triggerMyProcess() {
  36. // prepare data packet
  37. Map<String, Object> variables = new HashMap<String, Object>();
  38. Map<String, Object> subVariables = new HashMap<String, Object>();
  39. variables.put("maxTransCount", 1000000);
  40. variables.put("merchant", new Merchant("ICBC"));
  41. variables.put("protocol", "UM32");
  42. variables.put("repository", "10.10.38.99:/home/shirdrn/repository");
  43. variables.put("in", subVariables);
  44. variables.put("out", new HashMap<String, Object>());
  45. // start process instance
  46. ProcessInstance pi = runtimeService.startProcessInstanceByKey("MyReceiveTask", variables);
  47. assert (pi!=null);
  48. List<Execution> executions = runtimeService.createExecutionQuery().list();
  49. assert (executions.size()==1);
  50. Execution execution = runtimeService.createExecutionQuery().singleResult();
  51. runtimeService.setVariable(execution.getId(), "type", "receiveTask");
  52. runtimeService.signal(execution.getId());
  53. executions = runtimeService.createExecutionQuery().list();
  54. assert (executions.size()==1);
  55. execution = executions.get(0);
  56. runtimeService.setVariable(execution.getId(), "oper", mySpringBean.getName());
  57. runtimeService.signal(execution.getId());
  58. }
  59. }

运行程序,结果信息如下所示:

[java] view plaincopy
  1. 011-3-23 18:21:28 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
  2. 信息: Loading XML bean definitions from class path resource [activiti-context.xml]
  3. 2011-3-23 18:21:29 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
  4. 信息: Loading XML bean definitions from class path resource [org/shirdrn/workflow/activiti/spring/mySpringContext.xml]
  5. ... ...
  6. 2011-3-23 18:21:33 org.shirdrn.workflow.activiti.task.CheckBankReceiveTask execute
  7. 信息: i am CheckBankReceiveTask.
  8. in : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], maxTransCount=1000000, in={}, out={}}
  9. 2011-3-23 18:21:33 org.shirdrn.workflow.activiti.task.CheckMerchantReceiveTask execute
  10. 信息: i am CheckMerchantReceiveTask.
  11. in : {protocol=UM32, repository=10.10.38.99:/home/shirdrn/repository, merchant=Merchant[ICBC], maxTransCount=1000000, type=receiveTask, in={}, out={}

上述一部分是加载Spring配置,一部分是流程执行信息。

读书人网 >编程

热点推荐