本教程基于Activiti 6.0.0 ,着力介绍工作流引擎Activiti6.0.0引擎和Spring Boot的整合开发,帮助初学者入门。
Spring Boot 整合 Activiti 6.0.0 工作流引擎开发
本教程基于Activiti 6.0.0 ,着力介绍工作流引擎Activiti6.0.0引擎和Spring Boot的整合开发入门教程。
开发环境
11. Tomcat 7.0.78 22. JDK 7+ 33. Activiti 6.0.0 44. spring-boot-starter-parent 1.4.2.RELEASE 55. mybatis
maven
1<dependency> 2 <groupId>org.activiti</groupId> 3 <artifactId>activiti-spring-boot-starter-basic</artifactId> 4 <version>${activiti.version}</version> 5</dependency> 6 7<dependency> 8 <groupId>org.springframework.boot</groupId> 9 <artifactId>spring-boot-starter-data-jpa</artifactId> 10</dependency> 11 12<dependency> 13 <groupId>org.springframework.boot</groupId> 14 <artifactId>spring-boot-starter-data-rest</artifactId> 15</dependency>
多数据源配置
1package cn.showclear.utio.config; 2 3import cn.showclear.utio.mybatis.DataSources; 4import cn.showclear.utio.mybatis.ThreadLocalRountingDataSource; 5import org.activiti.spring.SpringAsyncExecutor; 6import org.activiti.spring.SpringProcessEngineConfiguration; 7import org.activiti.spring.boot.AbstractProcessEngineAutoConfiguration; 8import org.springframework.boot.context.properties.ConfigurationProperties; 9import org.springframework.context.annotation.*; 10import org.springframework.jdbc.datasource.DriverManagerDataSource; 11import org.springframework.transaction.PlatformTransactionManager; 12 13import javax.sql.DataSource; 14import java.io.IOException; 15import java.util.HashMap; 16import java.util.Map; 17 18/** 19 * Created by Yiyuery. 20 */ 21@Configuration 22@ComponentScan 23@PropertySource(value = {"classpath:/application.properties", 24 "file:/C:\\scooper\\utio\\db.properties","file:/icooper/config/utio/db.properties"}, 25 ignoreResourceNotFound = true) 26public class DataSourceConfig extends AbstractProcessEngineAutoConfiguration { 27 28 @Bean 29 @ConfigurationProperties(prefix="db.other") 30 public DataSource dataSourceaOther() { 31 return new DriverManagerDataSource(); 32 } 33 34 @Primary 35 @Bean(name = "dataSource") 36 public ThreadLocalRountingDataSource dataSource(){ 37 ThreadLocalRountingDataSource dataSource = new ThreadLocalRountingDataSource(); 38 dataSource.setDefaultTargetDataSource(dataSourceUtio()); 39 Map<Object , Object> dataSourceList = new HashMap(); 40 dataSourceList.put(DataSources.OTHER,dataSourceaOther()); 41 dataSource.setTargetDataSources(dataSourceList); 42 return dataSource; 43 } 44 45 @Bean 46 @ConfigurationProperties(prefix = "spring.datasource.activiti") 47 public DataSource dataSourceActiviti() { 48 return DataSourceBuilder.create().build(); 49 } 50 51 @Bean 52 public SpringProcessEngineConfiguration springProcessEngineConfiguration( 53 PlatformTransactionManager transactionManager, 54 SpringAsyncExecutor springAsyncExecutor) throws IOException { 55 56 return baseSpringProcessEngineConfiguration( 57 dataSourceActiviti(), 58 transactionManager, 59 springAsyncExecutor); 60 } 61}
核心配置文件
1/*resources/application.properties*/ 2spring.jpa.hibernate.ddl-auto=update 3spring.jpa.database=MYSQL 4spring.datasource.activiti.url=jdbc:mysql://192.168.106.104:3306/DB_SC_ACTIVITI?characterEncoding=UTF-8 5spring.datasource.activiti.username=showclear 6spring.datasource.activiti.password=showclear 7spring.datasource.activiti.driver-class-name=com.mysql.jdbc.Driver
SpringBoot 整合开发笔记
Activiti 简介
11、类似于OA的一种流式工作任务管理框架。 22、依赖于Activiti BPM引擎和BPMN 2.0
流程设计器的搭建
下载官方流程设计器
https://www.activiti.org/download-links
目前最新的版本是6.0.0

将解压后的wars放在Tomcat下:
并修改配置文件为mysql的连接方式
配置文件所在目录:tomcat\apache-tomcat-7.0.41\webapps\activiti-app\WEB-INF\classes\META-INF\activiti-app

初始化数据库
SpringBoot 整合开发
github
https://github.com/Activiti/Activiti
maven
1<!-- activiti-start --> 2 <dependency> 3 <groupId>org.activiti</groupId> 4 <artifactId>activiti-spring-boot-starter-basic</artifactId> 5 <version>${activiti.version}</version> 6 </dependency> 7 <!-- spring jpa中自带tomcat数据连接池 --> 8 <dependency> 9 <groupId>org.springframework.boot</groupId> 10 <artifactId>spring-boot-starter-data-jpa</artifactId> 11 </dependency>
1<dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-data-rest</artifactId> 4</dependency> 5 6> 数据源配置和工作流引擎对象创建 7 8@Configuration 9public class ActivitiConfig extends AbstractProcessEngineAutoConfiguration { 10 11 /** 12 * 工作流数据库 13 */ 14 @Autowired 15 @Qualifier("activiti") 16 private DataSource activitiDataSource; 17 18 /** 19 * 工作流 引擎对象创建 20 * @param transactionManager 21 * @param springAsyncExecutor 22 * @return 23 * @throws IOException 24 */ 25 @Bean 26 public SpringProcessEngineConfiguration springProcessEngineConfiguration( 27 PlatformTransactionManager transactionManager, 28 SpringAsyncExecutor springAsyncExecutor) throws IOException { 29 30 return baseSpringProcessEngineConfiguration( 31 activitiDataSource, 32 transactionManager, 33 springAsyncExecutor); 34 } 35 36}
/关于多数据源的配置方式网上有很多种,可以自己了解下/
> Activiti配置文件(用来生成和初始化数据库)
/文件需放在resources下的processes下/
1<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 4 5 <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> 6 <!-- 连接数据的配置 --> 7 <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property> 8 <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/DB_SC_ACTIVITI?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull"></property> 9 <property name="jdbcUsername" value="showclear"></property> 10 <property name="jdbcPassword" value="showclear"></property> 11 <property name="databaseSchemaUpdate" value="true" /> 12 <property name="history" value="full" /> 13 <property name="processDefinitionCacheLimit" value="10" /> 14 <property name="activityFontName" value="宋体"/> 15 <property name="labelFontName" value="宋体"/> 16 </bean></beans>
生成数据库
1 /** 2 * 使用配置文件来创建数据库中的表 3 */ 4 @Test 5 public void createTable() { 6 7 ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("processes/activiti.cfg.xml") 8 .buildProcessEngine(); 9 System.out.println(processEngine); 10 }
打开流程设计器

开发指导文档
https://www.activiti.org/userguide/6.latest/
工作流的部署和任务执行
以入廊申请为例
1 /** 2 * 入廊申请测试 3 * @author YF-XIACHAOYANG 4 * @date 2017/8/3 17:13 5 */ 6 public class EntryPipeApplication { 7 8 /** 9 * RepositoryService是管理流程定义的仓库服务的接口。 10 */ 11 private static RepositoryService repositoryService; 12 /** 13 * RuntimeService是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息,如执行管理,包括启动、推进、删除流程实例等操作。 14 */ 15 private static RuntimeService runtimeService; 16 /** 17 * TaskService是activiti的任务服务类。可以从这个类中获取任务的信息 18 */ 19 private static TaskService taskService; 20 /** 21 * HistoryService 是activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。 22 */ 23 private static HistoryService historyService; 24 /** 25 * 工作流核心引擎对象 26 */ 27 private static ProcessEngine processEngine; 28 29 @Before 30 public void init() { 31 createProcessEngine(); 32 } 33 34 private static String BPMN_XML_NAME = "EntryPipeApplication.bpmn20.xml"; 35 36 private static String BPMN_XML_DESC = "入廊申请工作流"; 37 38 /** 39 * 创建一个单例的ProcessEngine 40 */ 41 public void createProcessEngine() { 42 processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("processes/activiti.cfg.xml") 43 .buildProcessEngine(); 44 System.out.println("Activiti ProcessEngine Build Success!"); 45 getActivitiService(); 46 } 47 48 /** 49 * 获取activiti相关的service服务 50 */ 51 public void getActivitiService() { 52 repositoryService = processEngine.getRepositoryService(); 53 runtimeService = processEngine.getRuntimeService(); 54 taskService = processEngine.getTaskService(); 55 historyService = processEngine.getHistoryService(); 56 } 57 58 /** 59 * 部署流程定义 60 */ 61 @Test 62 public void deploymentProcessDefinition() { 63 64 Deployment deployment = repositoryService// 与流程定义和部署对象相关的service 65 .createDeployment()// 创建一个部署对象 66 .name(BPMN_XML_DESC)// 添加部署的名称 67 .addClasspathResource("processes/"+BPMN_XML_NAME)// classpath的资源中加载,一次只能加载 68 .deploy();// 完成部署 69 System.out.println("部署ID:" + deployment.getId()); 70 System.out.println("部署名称:" + deployment.getName()); 71 } 72 73 /** 74 * 启动一个入廊申请流程 75 */ 76 @Test 77 public void start() { 78 Map<String, Object> variables = new HashMap<String, Object>(); 79 //启动流程参数设置 80 String processId = runtimeService.startProcessInstanceByKey("entryPipeApplication", variables).getId(); 81 System.out.println("***************启动一个入廊申请流程完成***************" + processId); 82 //17501 83 } 84 85 /** 86 * 审核请假申请工作流查询 87 */ 88 @Test 89 public void queryRunTaskByTaskId() { 90 91 List<Task> list = processEngine.getTaskService()// 与正在执行的认为管理相关的Service 92 .createTaskQuery()// 创建任务查询对象 93 .list(); 94 if (list != null && list.size() > 0) { 95 for (Task task : list) { 96 String procId = task.getProcessInstanceId(); 97 if (procId.equals("17501")) { 98 System.out.println("#----------------------------------------#"); 99 System.out.println("任务ID:" + task.getId()); 100 System.out.println("任务名称:" + task.getName()); 101 System.out.println("任务的创建时间" + task); 102 System.out.println("任务的办理人:" + task.getAssignee()); 103 System.out.println("流程实例ID:" + task.getProcessInstanceId()); 104 System.out.println("执行对象ID:" + task.getExecutionId()); 105 System.out.println("流程定义ID:" + task.getProcessDefinitionId()); 106 System.out.println("#----------------------------------------#"); 107 } 108 } 109 } 110 111 } 112 113 /** 114 * 发起入廊申请[填写表单] 115 */ 116 @Test 117 public void startApplyTask(){ 118 String taskId="17505"; //任务Id 119 Map<String, Object> taskVariables = new HashMap<String, Object>(); 120 taskVariables.put("applyUserId", 123); 121 taskVariables.put("utId", 12); 122 taskVariables.put("deptUserId", 31); 123 //完成 124 processEngine.getTaskService()//与正在执行的认为管理相关的Service 125 .complete(taskId, taskVariables); 126 System.out.println("完成任务:任务ID:"+taskId); 127 } 128 129 /** 130 * 部门领导审核 131 */ 132 @Test 133 public void deptVerifyTask() { 134 String taskId="20008"; //任务Id 135 Map<String, Object> taskVariables = new HashMap<String, Object>(); 136 taskVariables.put("applyDeptApproved", 1); 137 taskVariables.put("deptOpinion", "通过!"); 138 taskVariables.put("opcUserId", 32); 139 //完成 140 processEngine.getTaskService()//与正在执行的认为管理相关的Service 141 .complete(taskId, taskVariables); 142 System.out.println("完成任务:任务ID:"+taskId); 143 } 144 145 /** 146 * 运维中心审核 147 */ 148 @Test 149 public void opcVerifyTask(){ 150 151 String taskId="22509"; //任务Id 152 Map<String, Object> taskVariables = new HashMap<String, Object>(); 153 taskVariables.put("applyOpcApproved", 1); 154 taskVariables.put("deptOpinion", "通过!"); 155 taskVariables.put("adminUserId", 33); 156 //完成 157 processEngine.getTaskService()//与正在执行的认为管理相关的Service 158 .complete(taskId, taskVariables); 159 System.out.println("完成任务:任务ID:"+taskId); 160 } 161 162 /** 163 * 行政部门审核 164 */ 165 @Test 166 public void adminVerifyTask(){ 167 168 String taskId="25008"; //任务Id 169 Map<String, Object> taskVariables = new HashMap<String, Object>(); 170 taskVariables.put("applyAdminApproved", 1); 171 taskVariables.put("deptOpinion", "通过!"); 172 173 //完成 174 processEngine.getTaskService()//与正在执行的认为管理相关的Service 175 .complete(taskId, taskVariables); 176 System.out.println("完成任务:任务ID:"+taskId); 177 } 178 179 /* 180 任务ID:2505 181 任务名称:发起入廊申请 182 任务的创建时间Task[id=2505, name=发起入廊申请] 183 任务的办理人:null 184 流程实例ID:2501 185 执行对象ID:2502 186 流程定义ID:entryPipeApplication:1:4 187 188 完成任务:任务ID:2505 189 190 再次查询: 191 任务ID:5006 192 任务名称:部门领导审核 193 任务的创建时间Task[id=5006, name=部门领导审核] 194 任务的办理人:null 195 流程实例ID:2501 196 执行对象ID:2502 197 流程定义ID:entryPipeApplication:1:4 198 199 任务ID:7505 200 任务名称:发起入廊申请 201 任务的创建时间Task[id=7505, name=发起入廊申请] 202 任务的办理人:null 203 流程实例ID:2501 204 执行对象ID:2502 205 流程定义ID:entryPipeApplication:1:4 206 207 完成任务:任务ID:7505 208 209 任务ID:10006 210 任务名称:部门领导审核 211 任务的创建时间Task[id=10006, name=部门领导审核] 212 任务的办理人:null 213 流程实例ID:2501 214 执行对象ID:2502 215 流程定义ID:entryPipeApplication:1:4 216 217 完成任务:任务ID:10006 218 219 任务ID:12505 220 任务名称:运维中心审核 221 任务的创建时间Task[id=12505, name=运维中心审核] 222 任务的办理人:null 223 流程实例ID:2501 224 执行对象ID:2502 225 流程定义ID:entryPipeApplication:1:4 226 #----------------------------------- 227 */ 228 229 }
国内比较成熟的工作流框架
Lemon OA
http://www.mossle.com/index.do
微信公众号

扫码关注或搜索架构探险之道获取最新文章,不积跬步无以至千里,坚持每周一更,坚持技术分享。我和你们一起成长 ^_^ !
本文分享自微信公众号 - 架构探险之道(zacsnz1314)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。