├── .gitignore ├── Chapter03 ├── README.md ├── activiti6-helloworld │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── coderdream │ │ │ │ └── activiti │ │ │ │ └── helloworld │ │ │ │ └── DemoMain.java │ │ └── resources │ │ │ ├── logback.xml │ │ │ └── second_approve.bpmn │ │ └── test │ │ ├── java │ │ └── com │ │ │ └── coderdream │ │ │ └── MyUnitTest.java │ │ └── resources │ │ ├── activiti.cfg.xml │ │ ├── log4j.properties │ │ └── my-process.bpmn20.xml └── images │ ├── 0305_01_IDEA_Setting_Terminal.png │ ├── 0307_01_Process.png │ ├── 0307_02_Add_Form.png │ ├── 0307_03_Form01.png │ ├── 0307_04_Form02.png │ └── 0307_05_Form03.png ├── Chapter04 ├── Chapter0410.md ├── Chapter0412.md ├── README.md ├── activiti-archetype-unittest2 │ ├── pom.xml │ └── src │ │ └── main │ │ └── resources │ │ ├── META-INF │ │ └── maven │ │ │ └── archetype-metadata.xml │ │ └── archetype-resources │ │ ├── pom.xml │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── DemoMain.java │ │ └── resources │ │ │ ├── activiti.cfg.xml │ │ │ ├── logback.xml │ │ │ └── second_approve.bpmn │ │ └── test │ │ ├── java │ │ └── MyUnitTest.java │ │ └── resources │ │ ├── activiti.cfg.xml │ │ ├── log4j.properties │ │ └── my-process.bpmn20.xml ├── activiti6-samples │ ├── config │ │ ├── pom.xml │ │ └── src │ │ │ ├── main │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── coderdream │ │ │ │ │ ├── DemoMain.java │ │ │ │ │ ├── delegate │ │ │ │ │ └── MDCErrorDelegate.java │ │ │ │ │ ├── event │ │ │ │ │ ├── CustomEventListener.java │ │ │ │ │ └── ProcessEventListener.java │ │ │ │ │ └── interceptor │ │ │ │ │ └── MDCCommandInvoker.java │ │ │ └── resources │ │ │ │ ├── activiti.cfg.xml │ │ │ │ ├── activiti_druid.cfg.xml │ │ │ │ ├── activiti_eventListener.cfg.xml │ │ │ │ ├── activiti_eventlog.cfg.xml │ │ │ │ ├── activiti_history.cfg.xml │ │ │ │ ├── activiti_mdc.cfg.xml │ │ │ │ ├── logback.xml │ │ │ │ └── second_approve.bpmn │ │ │ └── test │ │ │ ├── java │ │ │ └── com │ │ │ │ └── coderdream │ │ │ │ ├── MyUnitTest.java │ │ │ │ └── config │ │ │ │ ├── ConfigEventListenerTest.java │ │ │ │ ├── ConfigEventLogTest.java │ │ │ │ ├── ConfigHistoryLevelTest.java │ │ │ │ ├── ConfigMDCTest.java │ │ │ │ ├── ConfigTest.java │ │ │ │ └── ConfitDBTest.java │ │ │ └── resources │ │ │ ├── activiti.cfg.xml │ │ │ ├── log4j.properties │ │ │ ├── my-process.bpmn20.xml │ │ │ └── my-process_mdcerror.bpmn20.xml │ └── pom.xml └── images │ ├── 0401_Project_Structrue.png │ ├── 0402_Add_Archetype.png │ ├── 0403_Create_From_Archetype.png │ ├── 0404_ProcessEngineConfiguration.png │ ├── 0406_01.jpg │ ├── 0406_02.jpg │ ├── 0406_03.jpg │ ├── 0406_04.jpg │ ├── 0406_05.jpg │ ├── 0406_06.jpg │ ├── 041000_Result.png │ ├── 041001_ProcessEngineConfigurationImpl.png │ ├── 041002_initDatabaseEventLogging.png │ ├── 041003_EventLogger.png │ ├── 041004_addCloseListener.png │ ├── 041005_insert.png │ ├── 041101.jpg │ ├── 041102.jpg │ ├── 041103.jpg │ ├── 041104.jpg │ ├── 041105.jpg │ ├── 041201_ActivitiEventListener.png │ ├── 041202_BaseEntityEventListener.png │ ├── 041203_ActivitiEvent.png │ ├── 041204_ActivitiEntityEvent.png │ └── 041205_ActivitiVariableEvent.png ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | /target/ 25 | target/ 26 | .idea/ 27 | /.idea/ 28 | .idea 29 | *.idea 30 | *.iml -------------------------------------------------------------------------------- /Chapter03/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 第3章 Activiti6.0源码初探 4 | ### 3-1 本章概述 5 | ### 3-2 Activiti6.0源码初探-概览与获取 6 | ### 3-3 Activiti6.0源码初探-engine 7 | ### 3-4 Activiti6.0源码初探-模块介绍 8 | ### 3-5 Activiti6.0源码初探-activiti-app运行 9 | - 设置IDEA控制台: 10 | ![](images/0305_01_IDEA_Setting_Terminal.png) 11 | - 在控制台执行命令: 12 | ``` 13 | D:\Java\GitHub\Activiti6>cd modules/activiti-ui/activiti-app 14 | D:\Java\GitHub\Activiti6\modules\activiti-ui\activiti-app>mvn clean tomcat7:run 15 | ``` 16 | - 执行结果: 17 | ``` 18 | $ mvn clean tomcat7:run 19 | [INFO] Scanning for projects... 20 | [INFO] ------------------------------------------------------------------------ 21 | [INFO] Building activiti-app 6.0.0 22 | [INFO] ------------------------------------------------------------------------ 23 | ... 24 | [INFO] --- tomcat7-maven-plugin:2.2:run (default-cli) @ activiti-app --- 25 | [INFO] Running war on http://localhost:9999/activiti-app 26 | ... 27 | 一月 10, 2019 11:34:30 上午 org.apache.catalina.core.ApplicationContext log 28 | 信息: Initializing Spring FrameworkServlet 'apiDispatcher' 29 | 一月 10, 2019 11:34:33 上午 org.apache.catalina.core.ApplicationContext log 30 | 信息: Initializing Spring FrameworkServlet 'appDispatcher' 31 | 一月 10, 2019 11:34:33 上午 org.apache.coyote.AbstractProtocol start 32 | 信息: Starting ProtocolHandler ["http-nio-9999"] 33 | ``` 34 | ### 3-6 Activiti6.0源码初探-WebConfigurer 35 | ### 3-7 Activiti6.0源码初探-helloword-1 36 | 37 | - 完整流程图: 38 | ![](images/0307_01_Process.png) 39 | 40 | - 参考下图新增表单数据(注意类型、模式和是否必填): 41 | ![](images/0307_02_Add_Form.png) 42 | 43 | - 【填写审批信息】表单数据: 44 | ![](images/0307_03_Form01.png) 45 | 46 | - 【主管审批】表单数据: 47 | ![](images/0307_04_Form02.png) 48 | 49 | - 【人事审批】表单数据: 50 | ![](images/0307_05_Form03.png) 51 | 52 | 53 | ### 3-8 Activiti6.0源码初探-helloword-2 54 | 55 | - 代码清单:pom.xml 56 | ```xml 57 | 58 | 62 | 4.0.0 63 | 64 | com.coderdream.activiti 65 | activiti6-helloworld 66 | 1.0-SNAPSHOT 67 | 68 | 69 | 70 | org.activiti 71 | activiti-engine 72 | 6.0.0 73 | 74 | 75 | junit 76 | junit 77 | 4.12 78 | test 79 | 80 | 81 | ch.qos.logback 82 | logback-classic 83 | 1.1.11 84 | 85 | 86 | com.google.guava 87 | guava 88 | 23.0 89 | 90 | 91 | com.h2database 92 | h2 93 | 1.4.193 94 | 95 | 96 | 97 | 98 | ``` 99 | 100 | ### 3-9 Activiti6.0源码初探-helloword_idea-1 101 | 102 | 1、先梳理流程 103 | 104 | - 代码清单:DemoMain.java 105 | ```java 106 | public class DemoMain { 107 | 108 | private static final Logger LOGGER = LoggerFactory.getLogger(DemoMain.class); 109 | 110 | public static void main(String[] args) { 111 | LOGGER.info("启动我们的程序"); 112 | // 创建流程引擎 113 | // 部署流程定义文件 114 | // 启动运行流程 115 | // 处理流程任务 116 | LOGGER.info("结束我们的程序"); 117 | } 118 | 119 | } 120 | ``` 121 | 2、配置log,只打印简易信息: 122 | 123 | - 代码清单:logback.xml 124 | ```xml 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | ${plain} 136 | ${encoding} 137 | 138 | 139 | 140 | 141 | 143 | ${log.dir}/file.log 144 | 145 | ${log.dir}/file.%d{yyyy-MM-dd}.log 146 | 30 147 | 148 | 149 | ${std} 150 | ${encoding} 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | ``` 165 | 3、将流程文件拷贝到 resources 文件夹下: 166 | 167 | 4、完成完整流程代码 168 | - 代码清单:DemoMain.java 169 | ```java 170 | LOGGER.info("启动我们的程序"); 171 | // 创建流程引擎 172 | ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration(); 173 | ProcessEngine processEngine = cfg.buildProcessEngine(); 174 | String name = processEngine.getName(); 175 | String version = ProcessEngine.VERSION; 176 | LOGGER.info("流程引擎名称{},版本{}", name, version); 177 | // 部署流程定义文件 178 | RepositoryService repositoryService = processEngine.getRepositoryService(); 179 | DeploymentBuilder deploymentBuilder = repositoryService.createDeployment(); 180 | deploymentBuilder.addClasspathResource("second_approve.bpmn"); 181 | Deployment deployment = deploymentBuilder.deploy(); 182 | String deploymentId = deployment.getId(); 183 | ProcessDefinition processDefinition = repositoryService 184 | .createProcessDefinitionQuery() 185 | .deploymentId(deploymentId) 186 | .singleResult(); 187 | LOGGER.info("流程定义文件 [{}],流程ID [{}]", processDefinition.getName(), processDefinition.getId()); 188 | // 启动运行流程 189 | RuntimeService runtimeService = processEngine.getRuntimeService(); 190 | ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId()); 191 | LOGGER.info("启动流程 [{}]", processInstance.getProcessDefinitionKey()); 192 | // 处理流程任务 193 | TaskService taskService = processEngine.getTaskService(); 194 | List list = taskService.createTaskQuery().list(); 195 | for (Task task : list) { 196 | LOGGER.info("待处理任务 [{}]", task.getName()); 197 | } 198 | LOGGER.info("待处理任务数量 [{}]", list.size()); 199 | LOGGER.info("结束我们的程序"); 200 | ``` 201 | 5、测试代码 202 | - 运行结果: 203 | ``` 204 | 启动我们的程序 205 | 流程引擎名称default,版本6.0.0.4 206 | 流程定义文件 [二级审批],流程ID [second_approve:1:4] 207 | 启动流程 [second_approve] 208 | 待处理任务 [填写审批信息] 209 | 待处理任务数量 [1] 210 | 结束我们的程序 211 | ``` 212 | 213 | 214 | ### 3-10 Activiti6.0源码初探-helloword_idea-2 215 | ### 3-11 Activiti6.0源码初探-helloword_idea-3 216 | 217 | pom.xml设置 218 | 219 | 220 | - 增加parent 221 | ```xml 222 | 223 | org.springframework.boot 224 | spring-boot-starter-parent 225 | 2.0.0.RELEASE 226 | 227 | 228 | ``` 229 | 230 | - 新增依赖 231 | ```xml 232 | 233 | org.springframework.boot 234 | spring-boot-starter 235 | 236 | ``` 237 | 238 | - 新增plugin 239 | ```xml 240 | 241 | 242 | 243 | org.springframework.boot 244 | spring-boot-maven-plugin 245 | 246 | 247 | 248 | ``` 249 | 250 | - 命令行运行 251 | ```bash 252 | mvn spring-boot:run 253 | ``` 254 | - 打包 255 | ```bash 256 | mvn package 257 | ``` 258 | - 打包过程 259 | ```shell 260 | $ mvn package 261 | [INFO] Scanning for projects... 262 | [INFO] 263 | [INFO] ------------------------------------------------------------------------ 264 | [INFO] Building activiti6-helloworld 1.0-SNAPSHOT 265 | [INFO] ------------------------------------------------------------------------ 266 | [INFO] 267 | [INFO] --- maven-resources-plugin:3.0.1:resources (default-resources) @ activiti6-helloworld --- 268 | [INFO] Using 'UTF-8' encoding to copy filtered resources. 269 | [INFO] Copying 0 resource 270 | [INFO] Copying 2 resources 271 | [INFO] 272 | [INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ activiti6-helloworld --- 273 | [INFO] Nothing to compile - all classes are up to date 274 | [INFO] 275 | [INFO] --- maven-resources-plugin:3.0.1:testResources (default-testResources) @activiti6-helloworld --- 276 | [INFO] Using 'UTF-8' encoding to copy filtered resources. 277 | [INFO] skip non existing resourceDirectory D:\Java\GitHub\ActivitiInAction\Chapter03\activiti6-helloworld\src\test\resources 278 | [INFO] 279 | [INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ activiti6-helloworld --- 280 | [INFO] Nothing to compile - all classes are up to date 281 | [INFO] 282 | [INFO] --- maven-surefire-plugin:2.16:test (default-test) @ activiti6-helloworld --- 283 | [INFO] No tests to run. 284 | [INFO] 285 | [INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ activiti6-helloworld --- 286 | [INFO] Building jar: D:\Java\GitHub\ActivitiInAction\Chapter03\activiti6-helloworld\target\activiti6-helloworld-1.0-SNAPSHOT.jar 287 | [INFO] 288 | [INFO] --- spring-boot-maven-plugin:2.0.0.RELEASE:repackage (default) @ activiti6-helloworld --- 289 | [INFO] ------------------------------------------------------------------------ 290 | [INFO] BUILD SUCCESS 291 | [INFO] ------------------------------------------------------------------------ 292 | [INFO] Total time: 7.046 s 293 | [INFO] Finished at: 2019-01-11T09:32:41+08:00 294 | [INFO] Final Memory: 22M/267M 295 | [INFO] ------------------------------------------------------------------------ 296 | ``` 297 | 298 | - 查看打包结果 299 | ``` 300 | Admin@Admin-PC MINGW64 /d/Java/GitHub/ActivitiInAction/Chapter03/activiti6-helloworld (master) 301 | $ cd target 302 | 303 | Admin@Admin-PC MINGW64 /d/Java/GitHub/ActivitiInAction/Chapter03/activiti6-helloworld/target (master) 304 | $ ll 305 | total 18988 306 | -rw-r--r-- 1 Admin 197121 19429358 一月 11 09:32 activiti6-helloworld-1.0-SNAPSHOT.jar 307 | -rw-r--r-- 1 Admin 197121 8581 一月 11 09:32 activiti6-helloworld-1.0-SNAPSHOT.jar.original 308 | drwxr-xr-x 1 Admin 197121 0 一月 11 09:03 classes 309 | drwxr-xr-x 1 Admin 197121 0 一月 10 10:35 generated-sources 310 | drwxr-xr-x 1 Admin 197121 0 一月 11 08:54 logs 311 | drwxr-xr-x 1 Admin 197121 0 一月 11 09:32 maven-archiver 312 | drwxr-xr-x 1 Admin 197121 0 一月 10 17:09 maven-status 313 | 314 | ``` 315 | 316 | - 通过Java命令执行 317 | ```bath 318 | java -jar activiti6-helloworld-1.0-SNAPSHOT.jar 319 | ``` -------------------------------------------------------------------------------- /Chapter03/activiti6-helloworld/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | 9 | org.springframework.boot 10 | spring-boot-starter-parent 11 | 2.0.0.RELEASE 12 | 13 | 14 | 15 | com.coderdream.activiti 16 | activiti6-helloworld 17 | 1.0-SNAPSHOT 18 | 19 | -Dfile.encoding=UTF-8 20 | 21 | 22 | 23 | org.activiti 24 | activiti-engine 25 | 6.0.0 26 | 27 | 28 | junit 29 | junit 30 | 4.12 31 | test 32 | 33 | 34 | ch.qos.logback 35 | logback-classic 36 | 1.1.11 37 | 38 | 39 | com.google.guava 40 | guava 41 | 23.0 42 | 43 | 44 | com.h2database 45 | h2 46 | 1.3.176 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-maven-plugin 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Chapter03/activiti6-helloworld/src/main/java/com/coderdream/activiti/helloworld/DemoMain.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.activiti.helloworld; 2 | 3 | import com.google.common.collect.Maps; 4 | import org.activiti.engine.*; 5 | import org.activiti.engine.form.FormProperty; 6 | import org.activiti.engine.form.TaskFormData; 7 | import org.activiti.engine.impl.form.DateFormType; 8 | import org.activiti.engine.impl.form.StringFormType; 9 | import org.activiti.engine.repository.Deployment; 10 | import org.activiti.engine.repository.DeploymentBuilder; 11 | import org.activiti.engine.repository.ProcessDefinition; 12 | import org.activiti.engine.runtime.ProcessInstance; 13 | import org.activiti.engine.task.Task; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | import java.text.ParseException; 18 | import java.text.SimpleDateFormat; 19 | import java.util.Date; 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.Scanner; 23 | 24 | public class DemoMain { 25 | 26 | /** 27 | * logger 28 | */ 29 | private static final Logger LOGGER = LoggerFactory.getLogger(DemoMain.class); 30 | 31 | public static void main(String[] args) throws ParseException { 32 | LOGGER.info("启动我们的程序"); 33 | // 创建流程引擎 34 | ProcessEngine processEngine = getProcessEngine(); 35 | 36 | // 部署流程定义文件 37 | ProcessDefinition processDefinition = getProcessDefinition(processEngine); 38 | 39 | // 启动运行流程 40 | ProcessInstance processInstance = getProcessInstance(processEngine, processDefinition); 41 | 42 | // 处理流程任务 43 | processTask(processEngine, processInstance); 44 | 45 | LOGGER.info("结束我们的程序"); 46 | } 47 | 48 | private static void processTask(ProcessEngine processEngine, ProcessInstance processInstance) throws ParseException { 49 | Scanner scanner = new Scanner(System.in); 50 | while (processInstance != null && !processInstance.isEnded()) { 51 | TaskService taskService = processEngine.getTaskService(); 52 | List list = taskService.createTaskQuery().list(); 53 | LOGGER.info("待处理任务数量 [{}]", list.size()); 54 | for (Task task : list) { 55 | LOGGER.info("待处理任务 [{}]", task.getName()); 56 | Map variables = getMap(processEngine, scanner, task); 57 | 58 | // 提交工作 59 | taskService.complete(task.getId(), variables); 60 | // 同步流程状态 61 | processInstance = processEngine 62 | .getRuntimeService() 63 | .createProcessInstanceQuery() 64 | .processInstanceId(processInstance.getId()) 65 | .singleResult(); 66 | } 67 | } 68 | scanner.close(); 69 | } 70 | 71 | private static Map getMap(ProcessEngine processEngine, Scanner scanner, Task task) throws ParseException { 72 | FormService formService = processEngine.getFormService(); 73 | TaskFormData taskFormData = formService.getTaskFormData(task.getId()); 74 | List formProperties = taskFormData.getFormProperties(); 75 | Map variables = Maps.newHashMap(); 76 | for (FormProperty property : formProperties) { 77 | String line = null; 78 | if (StringFormType.class.isInstance(property.getType())) { 79 | LOGGER.info("请输入 {} ?", property.getName()); 80 | line = scanner.nextLine(); 81 | variables.put(property.getId(), line); 82 | } else if (DateFormType.class.isInstance(property.getType())) { 83 | LOGGER.info("请输入 {} ? 格式 (yyyy-MM-dd)", property.getName()); 84 | line = scanner.nextLine(); 85 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 86 | Date date = dateFormat.parse(line); 87 | variables.put(property.getId(), date); 88 | } else { 89 | LOGGER.info("类型暂不支持 [{}] ", property.getType()); 90 | } 91 | LOGGER.info("您输入的内容是 [{}] :", line); 92 | } 93 | return variables; 94 | } 95 | 96 | private static ProcessInstance getProcessInstance(ProcessEngine processEngine, ProcessDefinition processDefinition) { 97 | RuntimeService runtimeService = processEngine.getRuntimeService(); 98 | ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId()); 99 | LOGGER.info("启动流程 [{}]", processInstance.getProcessDefinitionKey()); 100 | return processInstance; 101 | } 102 | 103 | private static ProcessDefinition getProcessDefinition(ProcessEngine processEngine) { 104 | RepositoryService repositoryService = processEngine.getRepositoryService(); 105 | DeploymentBuilder deploymentBuilder = repositoryService.createDeployment(); 106 | deploymentBuilder.addClasspathResource("second_approve.bpmn"); 107 | Deployment deployment = deploymentBuilder.deploy(); 108 | String deploymentId = deployment.getId(); 109 | ProcessDefinition processDefinition = repositoryService 110 | .createProcessDefinitionQuery() 111 | .deploymentId(deploymentId) 112 | .singleResult(); 113 | LOGGER.info("流程定义文件 [{}],流程ID [{}]", processDefinition.getName(), processDefinition.getId()); 114 | return processDefinition; 115 | } 116 | 117 | private static ProcessEngine getProcessEngine() { 118 | ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration(); 119 | ProcessEngine processEngine = cfg.buildProcessEngine(); 120 | String name = processEngine.getName(); 121 | String version = ProcessEngine.VERSION; 122 | LOGGER.info("流程引擎名称{},版本{}", name, version); 123 | return processEngine; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Chapter03/activiti6-helloworld/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ${plain} 12 | ${encoding} 13 | 14 | 15 | 16 | 17 | 19 | ${log.dir}/file.log 20 | 21 | ${log.dir}/file.%d{yyyy-MM-dd}.log 22 | 30 23 | 24 | 25 | ${std} 26 | ${encoding} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter03/activiti6-helloworld/src/main/resources/second_approve.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /Chapter03/activiti6-helloworld/src/test/java/com/coderdream/MyUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.coderdream; 2 | 3 | import org.activiti.engine.runtime.ProcessInstance; 4 | import org.activiti.engine.task.Task; 5 | import org.activiti.engine.test.ActivitiRule; 6 | import org.activiti.engine.test.Deployment; 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | import static org.junit.Assert.assertNotNull; 12 | 13 | public class MyUnitTest { 14 | 15 | @Rule 16 | public ActivitiRule activitiRule = new ActivitiRule(); 17 | 18 | @Test 19 | @Deployment(resources = {"com/coderdream/my-process.bpmn20.xml"}) 20 | public void test() { 21 | ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process"); 22 | assertNotNull(processInstance); 23 | 24 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 25 | assertEquals("Activiti is awesome!", task.getName()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Chapter03/activiti6-helloworld/src/test/resources/activiti.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter03/activiti6-helloworld/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, CA 2 | 3 | # ConsoleAppender 4 | log4j.appender.CA=org.apache.log4j.ConsoleAppender 5 | log4j.appender.CA.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n 7 | 8 | 9 | log4j.logger.org.apache.ibatis.level=INFO 10 | log4j.logger.javax.activation.level=INFO 11 | -------------------------------------------------------------------------------- /Chapter03/activiti6-helloworld/src/test/resources/my-process.bpmn20.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Chapter03/images/0305_01_IDEA_Setting_Terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter03/images/0305_01_IDEA_Setting_Terminal.png -------------------------------------------------------------------------------- /Chapter03/images/0307_01_Process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter03/images/0307_01_Process.png -------------------------------------------------------------------------------- /Chapter03/images/0307_02_Add_Form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter03/images/0307_02_Add_Form.png -------------------------------------------------------------------------------- /Chapter03/images/0307_03_Form01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter03/images/0307_03_Form01.png -------------------------------------------------------------------------------- /Chapter03/images/0307_04_Form02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter03/images/0307_04_Form02.png -------------------------------------------------------------------------------- /Chapter03/images/0307_05_Form03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter03/images/0307_05_Form03.png -------------------------------------------------------------------------------- /Chapter04/Chapter0410.md: -------------------------------------------------------------------------------- 1 | 2 | ## 4-10 事件处理及监听器配置-eventlog 3 | 4 | ### 最佳实践 5 | 6 | 1. 新建配置文件activiti_eventlog.cfg.xml,设置 enableDatabaseEventLogging 为 true; 7 | 2. 新增测试类 ConfigEventLogTest,打印事件日志 8 | 9 | - 代码清单1:activiti_eventlog.cfg.xml 10 | ```xml 11 | 12 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ``` 27 | 28 | - 代码清单2:ConfigEventLogTest.java 29 | ```java 30 | @Rule 31 | public ActivitiRule activitiRule = new ActivitiRule("activiti_eventlog.cfg.xml"); 32 | 33 | @Test 34 | @Deployment(resources = {"my-process.bpmn20.xml"}) 35 | public void test() { 36 | ProcessInstance processInstance = activitiRule.getRuntimeService() 37 | .startProcessInstanceByKey("my-process"); 38 | 39 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 40 | 41 | // 继续执行流程 42 | activitiRule.getTaskService().complete(task.getId()); 43 | 44 | 45 | List eventLogEntries = activitiRule.getManagementService() 46 | .getEventLogEntriesByProcessInstanceId(processInstance.getProcessInstanceId()); 47 | for (EventLogEntry eventLogEntry : eventLogEntries) { 48 | LOGGER.info("eventLogEntry = {}, eventLog.data = {}", eventLogEntry, new String(eventLogEntry.getData())); 49 | } 50 | LOGGER.info("eventLogEntries.size = {}", eventLogEntries.size()); 51 | } 52 | ``` 53 | 54 | - 结果分析(12条记录): 55 | ![](images/041000_Result.png) 56 | 57 | - 完整运行结果: 58 | ``` 59 | 09:56:37.045 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:36 CST 2019 : PROCESSINSTANCE_START, eventLog.data = {"timeStamp":1547776596844,"processDefinitionId":"my-process:1:3","createTime":1547776596844,"id":"4"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 60 | 09:56:37.046 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:36 CST 2019 : ACTIVITY_STARTED, eventLog.data = {"timeStamp":1547776596851,"activityId":"start","processDefinitionId":"my-process:1:3","processInstanceId":"4","executionId":"5","behaviorClass":"org.activiti.engine.impl.bpmn.behavior.NoneStartEventActivityBehavior","activityType":"startEvent"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 61 | 09:56:37.046 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:36 CST 2019 : ACTIVITY_COMPLETED, eventLog.data = {"timeStamp":1547776596853,"activityId":"start","processDefinitionId":"my-process:1:3","processInstanceId":"4","executionId":"5","behaviorClass":"org.activiti.engine.impl.bpmn.behavior.NoneStartEventActivityBehavior","activityType":"startEvent"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 62 | 09:56:37.046 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:36 CST 2019 : SEQUENCEFLOW_TAKEN, eventLog.data = {"targetActivityId":"someTask","timeStamp":1547776596856,"targetActivityBehaviorClass":"org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior","sourceActivityType":"org.activiti.bpmn.model.StartEvent","targetActivityName":"Activiti is awesome!","id":"flow1","sourceActivityBehaviorClass":"org.activiti.engine.impl.bpmn.behavior.NoneStartEventActivityBehavior","targetActivityType":"org.activiti.bpmn.model.UserTask","sourceActivityId":"start"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 63 | 09:56:37.046 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:36 CST 2019 : ACTIVITY_STARTED, eventLog.data = {"timeStamp":1547776596858,"activityId":"someTask","processDefinitionId":"my-process:1:3","processInstanceId":"4","executionId":"5","behaviorClass":"org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior","activityName":"Activiti is awesome!","activityType":"userTask"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 64 | 09:56:37.046 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:36 CST 2019 : TASK_CREATED, eventLog.data = {"timeStamp":1547776596873,"taskDefinitionKey":"someTask","processDefinitionId":"my-process:1:3","processInstanceId":"4","executionId":"5","createTime":1547776596858,"name":"Activiti is awesome!","id":"8","priority":50} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 65 | 09:56:37.047 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:36 CST 2019 : TASK_COMPLETED, eventLog.data = {"duration":141,"timeStamp":1547776596999,"taskDefinitionKey":"someTask","processDefinitionId":"my-process:1:3","processInstanceId":"4","executionId":"5","createTime":1547776596858,"name":"Activiti is awesome!","id":"8","priority":50} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 66 | 09:56:37.047 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:37 CST 2019 : ACTIVITY_COMPLETED, eventLog.data = {"timeStamp":1547776597011,"activityId":"someTask","processDefinitionId":"my-process:1:3","processInstanceId":"4","executionId":"5","behaviorClass":"org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior","activityName":"Activiti is awesome!","activityType":"userTask"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 67 | 09:56:37.047 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:37 CST 2019 : SEQUENCEFLOW_TAKEN, eventLog.data = {"targetActivityId":"end","timeStamp":1547776597012,"sourceActivityName":"Activiti is awesome!","targetActivityBehaviorClass":"org.activiti.engine.impl.bpmn.behavior.NoneEndEventActivityBehavior","sourceActivityType":"org.activiti.bpmn.model.UserTask","id":"flow2","sourceActivityBehaviorClass":"org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior","targetActivityType":"org.activiti.bpmn.model.EndEvent","sourceActivityId":"someTask"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 68 | 09:56:37.048 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:37 CST 2019 : ACTIVITY_STARTED, eventLog.data = {"timeStamp":1547776597013,"activityId":"end","processDefinitionId":"my-process:1:3","processInstanceId":"4","executionId":"5","behaviorClass":"org.activiti.engine.impl.bpmn.behavior.NoneEndEventActivityBehavior","activityType":"endEvent"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 69 | 09:56:37.048 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:37 CST 2019 : ACTIVITY_COMPLETED, eventLog.data = {"timeStamp":1547776597013,"activityId":"end","processDefinitionId":"my-process:1:3","processInstanceId":"4","executionId":"5","behaviorClass":"org.activiti.engine.impl.bpmn.behavior.NoneEndEventActivityBehavior","activityType":"endEvent"} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 70 | 09:56:37.048 [main] [INFO] eventLogEntry = Fri Jan 18 09:56:37 CST 2019 : PROCESSINSTANCE_END, eventLog.data = {"timeStamp":1547776597028,"processDefinitionId":"my-process:1:3","id":"4","endTime":1547776597028} ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:42 71 | 09:56:37.048 [main] [INFO] eventLogEntries.size = 12 ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.c.ConfigEventLogTest.test:44 72 | 73 | Process finished with exit code 0 74 | ``` 75 | 76 | ### 代码分析 77 | 78 | 1. 在配置文件中设置的值,会在 ProcessEngineConfigurationImpl 的 setEnableDatabaseEventLogging 方法中生效: 79 | ![](images/041001_ProcessEngineConfigurationImpl.png) 80 | 81 | 2. 如果设置为true,则在 initDatabaseEventLogging 方法中会新建一个 EventLogger 对象: 82 | ![](images/041002_initDatabaseEventLogging.png) 83 | 84 | 3. EventLogger 的初始化动作: 85 | ![](images/041003_EventLogger.png) 86 | 87 | 4. EventLogger 会新增 EventFlusher(DatabaseEventFlusher) 对象到 Close 监听器: 88 | ![](images/041004_addCloseListener.png) 89 | 90 | 5. 在 DatabaseEventFlusher 的 close 方法中将记录插入数据库: 91 | ![](images/041005_insert.png) 92 | -------------------------------------------------------------------------------- /Chapter04/Chapter0412.md: -------------------------------------------------------------------------------- 1 | 2 | ## 4-12 事件处理及监听器配置-eventLinstener 3 | 4 | 5 | ### 6 | 7 | - 主要内容 8 | ![](images/041101.jpg) 9 | - 事件及监听器原理 10 | ![](images/041102.jpg) 11 | - 监听器配置方式 12 | ![](images/041103.jpg) 13 | - Activiti事件监听 14 | ![](images/041104.jpg) 15 | - 相关API 16 | ![](images/041105.jpg) 17 | 18 | ## 最佳实践 19 | 20 | 1. 新建流程事件监听器 ProcessEventListener 和自定义事件监听器 CustomEventListener 21 | 2. 新建配置文件 activiti_eventListener.cfg.xml,设置监听类; 22 | 3. 新增测试类 ConfigEventListenerTest,查看执行结果 23 | 24 | ### 情形一:配置监听类 25 | 26 | - 代码清单1:activiti_eventListener.cfg.xml 27 | ```xml 28 | 29 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | ``` 48 | 49 | - 代码清单2:ConfigEventListenerTest.java 50 | ```java 51 | public class ConfigEventListenerTest { 52 | 53 | /** logger */ 54 | private static final Logger LOGGER = LoggerFactory.getLogger(ConfigEventListenerTest.class); 55 | 56 | @Rule 57 | public ActivitiRule activitiRule = new ActivitiRule("activiti_eventListener.cfg.xml"); 58 | 59 | @Test 60 | @Deployment(resources = {"my-process.bpmn20.xml"}) 61 | public void test() { 62 | ProcessInstance processInstance = activitiRule.getRuntimeService() 63 | .startProcessInstanceByKey("my-process"); 64 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 65 | // 继续执行流程 66 | activitiRule.getTaskService().complete(task.getId()); 67 | } 68 | 69 | } 70 | ``` 71 | 72 | - 运行结果: 73 | ``` 74 | 14:26:36.770 [main] [INFO] 流程启动 PROCESS_STARTED 4 ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.e.ProcessEventListener.onEvent:19 75 | 14:26:36.966 [main] [INFO] 流程结束 PROCESS_COMPLETED 4 ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.e.ProcessEventListener.onEvent:21 76 | ``` 77 | 78 | ### 情形二:配置特定监听类型 79 | 80 | ```xml 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | ``` 92 | 93 | - 运行结果: 94 | ``` 95 | 14:29:41.461 [main] [INFO] ProcessEngine default created ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.ProcessEngineImpl.:87 96 | 14:29:41.661 [main] [INFO] 流程启动 PROCESS_STARTED 4 ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.e.ProcessEventListener.onEvent:19 97 | 98 | ``` 99 | ### 情形三:配置自定义监听 100 | 101 | ```xml 102 | 103 | 104 | 105 | 106 | 107 | 108 | ``` 109 | 110 | - 运行结果 111 | ``` 112 | 14:35:17.609 [main] [INFO] ProcessEngine default created ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.ProcessEngineImpl.:87 113 | 14:35:17.928 [main] [INFO] 监听到自定义事件 CUSTOM null ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.e.CustomEventListener.onEvent:19 114 | 115 | Process finished with exit code 0 116 | ``` 117 | 118 | ### 情形四:在源代码中配置自定义监听 119 | 120 | - 代码清单: 121 | ```java 122 | @Test 123 | @Deployment(resources = {"my-process.bpmn20.xml"}) 124 | public void test() { 125 | ProcessInstance processInstance = activitiRule.getRuntimeService() 126 | .startProcessInstanceByKey("my-process"); 127 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 128 | // 继续执行流程 129 | activitiRule.getTaskService().complete(task.getId()); 130 | // 通过代码添加监听器(非配置文件方式) 131 | activitiRule.getRuntimeService().addEventListener(new CustomEventListener()); 132 | // 添加一个自定义事件 133 | activitiRule.getRuntimeService().dispatchEvent(new ActivitiEventImpl(ActivitiEventType.CUSTOM)); 134 | } 135 | ``` 136 | 137 | - 运行结果 138 | ``` 139 | 14:35:17.609 [main] [INFO] ProcessEngine default created ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.ProcessEngineImpl.:87 140 | 14:35:17.928 [main] [INFO] 监听到自定义事件 CUSTOM null ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= c.c.e.CustomEventListener.onEvent:19 141 | 142 | Process finished with exit code 0 143 | ``` 144 | 145 | ### 代码分析 146 | 147 | 1. ActivitiEventListener 继承关系: 148 | ![](images/041201_ActivitiEventListener.png) 149 | 150 | 2. BaseEntityEventListener: 151 | ![](images/041202_BaseEntityEventListener.png) 152 | 153 | 3. ActivitiEvent: 154 | ![](images/041203_ActivitiEvent.png) 155 | 156 | 4. ActivitiEntityEvent: 157 | ![](images/041204_ActivitiEntityEvent.png) 158 | 159 | 5. ActivitiVariableEvent: 160 | ![](images/041205_ActivitiVariableEvent.png) 161 | -------------------------------------------------------------------------------- /Chapter04/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 第4章 Activiti6.0引擎配置 3 | ### 4-1 本章概述 4 | ### 4-2 创建流程引擎配置-config_samples 5 | 6 | 1. 新建Maven空项目activiti-samples 7 | 2. 给项目新增Module,名称为config 8 | 3. 新增自定义脚手架 9 | ![](images/0402_Add_Archetype.png) 10 | 4. 根据脚手架创建模块 11 | ![](images/0403_Create_From_Archetype.png) 12 | 5. 新建测试文件,路径 activiti6-samples\config\src\test\java\com\coderdream\config,名称 ConfigTest.java: 13 | ![](images/0401_Project_Structrue.png) 14 | - 代码清单:ConfigTest.java 15 | ```java 16 | @Test 17 | public void testConfig1() { 18 | ProcessEngineConfiguration configuration = ProcessEngineConfiguration 19 | .createProcessEngineConfigurationFromResourceDefault(); 20 | 21 | LOGGER.info("configuration = {}", configuration); 22 | } 23 | 24 | @Test 25 | public void testConfig2() { 26 | ProcessEngineConfiguration configuration = ProcessEngineConfiguration 27 | .createStandaloneProcessEngineConfiguration(); 28 | 29 | LOGGER.info("configuration = {}", configuration); 30 | } 31 | ``` 32 | 33 | - 输出结果: 34 | ``` 35 | configuration = org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration@2beee7ff 36 | configuration = org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration@366647c2 37 | ``` 38 | - 流程引擎配置的继承关系 39 | ![](images/0404_ProcessEngineConfiguration.png) 40 | 41 | ### 4-3 创建流程引擎配置-archetype 42 | ### 4-4 数据库配置-dbconfig 43 | ### 4-5 数据库配置-dbconfig_code 44 | 45 | ```java 46 | @Test 47 | public void testConfig1() { 48 | ProcessEngineConfiguration configuration = ProcessEngineConfiguration 49 | .createProcessEngineConfigurationFromResourceDefault(); 50 | 51 | LOGGER.info("configuration = {}", configuration); 52 | ProcessEngine processEngine = configuration.buildProcessEngine(); 53 | LOGGER.info("获取流程引擎 {}", processEngine.getName()); 54 | processEngine.close(); 55 | } 56 | ``` 57 | 58 | 59 | ``` 60 | Loading XML bean definitions from class path resource [activiti.cfg.xml] 61 | configuration = org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration@6a6afff2 62 | Activiti 5 compatibility handler implementation not found or error during instantiation : org.activiti.compatibility.DefaultActiviti5CompatibilityHandler. Activiti 5 backwards compatibility disabled. 63 | performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql 64 | performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql 65 | performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql 66 | ProcessEngine default created 67 | 获取流程引擎 default 68 | performing drop on engine with resource org/activiti/db/drop/activiti.h2.drop.engine.sql 69 | performing drop on history with resource org/activiti/db/drop/activiti.h2.drop.history.sql 70 | performing drop on identity with resource org/activiti/db/drop/activiti.h2.drop.identity.sql 71 | 72 | Process finished with exit code 0 73 | ``` 74 | 75 | 76 | ### 4-6 日志记录配置-logging 77 | 78 | ![](images/0406_01.jpg) 79 | 80 | ![](images/0406_02.jpg) 81 | 82 | ![](images/0406_03.jpg) 83 | 84 | ![](images/0406_04.jpg) 85 | 86 | ![](images/0406_05.jpg) 87 | 88 | ![](images/0406_06.jpg) 89 | 90 | ### 4-7 日志记录配置-logging_mdc 91 | 92 | 步骤: 93 | 1. 创建代理; 94 | 2. 修改流程文件; 95 | 3. 修改logback文件 96 | 3. 打开MDC 97 | 98 | 99 | - 代码清单:MDCErrorDelegate.java 100 | ```java 101 | public class MDCErrorDelegate implements JavaDelegate { 102 | 103 | /** logger */ 104 | private static final Logger LOGGER = LoggerFactory.getLogger(MDCErrorDelegate.class); 105 | 106 | @Override 107 | public void execute(DelegateExecution execution) { 108 | LOGGER.info("run MDCErrorDelegate"); 109 | throw new RuntimeException("only test"); 110 | } 111 | } 112 | 113 | ``` 114 | - 代码清单:my-process.bpmn20.xml 115 | ```xml 116 | 117 | 118 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | ``` 140 | 141 | - 代码清单(片段):logback.xml 142 | ```xml 143 | 150 | 156 | 157 | 158 | 159 | 160 | ${mdc} 161 | ${encoding} 162 | 163 | 164 | ``` 165 | 166 | 167 | - 代码清单:ConfigMDCTest.java 168 | ```java 169 | public class ConfigMDCTest { 170 | 171 | /** logger */ 172 | private static final Logger LOGGER = LoggerFactory.getLogger(ConfigMDCTest.class); 173 | 174 | @Rule 175 | public ActivitiRule activitiRule = new ActivitiRule(); 176 | 177 | @Test 178 | @Deployment(resources = {"my-process.bpmn20.xml"}) 179 | public void test() { 180 | // 打开MDC开关 181 | LogMDC.setMDCEnabled(true); 182 | ProcessInstance processInstance = activitiRule.getRuntimeService() 183 | .startProcessInstanceByKey("my-process"); 184 | assertNotNull(processInstance); 185 | 186 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 187 | assertEquals("Activiti is awesome!", task.getName()); 188 | 189 | // 继续执行流程 190 | activitiRule.getTaskService().complete(task.getId()); 191 | } 192 | 193 | } 194 | ``` 195 | 196 | - 执行结果 197 | ``` 198 | 15:32:05.953 [main] [ERROR] Error while closing command context ProcessDefinitionId=my-process:1:3 199 | executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.CommandContext.logException:122 200 | java.lang.RuntimeException: only test 201 | at com.coderdream.delegate.MDCErrorDelegate.execute(MDCErrorDelegate.java:16) 202 | ``` 203 | 204 | **拦截器方式** 205 | 206 | 1. 新增拦截器 207 | 2. 新增配置文件 208 | 3. 新增测试方法及相关配置 209 | 210 | - 代码清单1:MDCCommandInvoker.java 211 | ```java 212 | public class MDCCommandInvoker extends DebugCommandInvoker { 213 | 214 | // 参考DebugCommandInvoker代码 215 | @Override 216 | public void executeOperation(Runnable runnable) { 217 | // 保存默认状态 218 | boolean mdcEnabled = LogMDC.isMDCEnabled(); 219 | // 修改状态 220 | LogMDC.setMDCEnabled(true); 221 | if (runnable instanceof AbstractOperation) { 222 | AbstractOperation operation = (AbstractOperation) runnable; 223 | 224 | if (operation.getExecution() != null) { 225 | // 记录日志 226 | LogMDC.putMDCExecution(operation.getExecution()); 227 | } 228 | 229 | } 230 | 231 | super.executeOperation(runnable); 232 | // 清理上下文信息 233 | LogMDC.clear(); 234 | // 还原为默认状态 235 | if (!mdcEnabled) { 236 | LogMDC.setMDCEnabled(false); 237 | } 238 | } 239 | } 240 | ``` 241 | 242 | - 代码清单2:activiti_mdc.cfg.xml 243 | ```xml 244 | 245 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | ``` 259 | 260 | - 代码清单3:my-process_mdcerror.bpmn20.xml 261 | ```xml 262 | 263 | 264 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | ``` 285 | 286 | - 代码清单4:ConfigMDCTest.java 287 | ```java 288 | @Rule 289 | public ActivitiRule activitiRule = new ActivitiRule("activiti_mdc.cfg.xml"); 290 | 291 | @Test 292 | @Deployment(resources = {"my-process_mdcerror.bpmn20.xml"}) 293 | public void test2() { 294 | ProcessInstance processInstance = activitiRule.getRuntimeService() 295 | .startProcessInstanceByKey("my-process"); 296 | assertNotNull(processInstance); 297 | 298 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 299 | assertEquals("Activiti is awesome!", task.getName()); 300 | 301 | // 继续执行流程 302 | activitiRule.getTaskService().complete(task.getId()); 303 | } 304 | ``` 305 | 306 | 307 | - 运行结果 308 | ``` 309 | 15:54:38.046 [main] [INFO] performing create on engine with resource org/activiti/db/create/activiti.h2.create.engine.sql 310 | ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.d.DbSqlSession.executeSchemaResource:1147 311 | 15:54:38.100 [main] [INFO] performing create on history with resource org/activiti/db/create/activiti.h2.create.history.sql 312 | ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.d.DbSqlSession.executeSchemaResource:1147 313 | 15:54:38.104 [main] [INFO] performing create on identity with resource org/activiti/db/create/activiti.h2.create.identity.sql 314 | ProcessDefinitionId= executionId= mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.d.DbSqlSession.executeSchemaResource:1147 315 | 15:54:38.108 [main] [INFO] ProcessEngine default created ProcessDefinitionId= 316 | executionId= mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.ProcessEngineImpl.:87 317 | 15:54:38.303 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.ContinueProcessOperation : 318 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 319 | 15:54:38.307 [main] [INFO] 320 | 4 (process instance) 321 | └── 5 : start (StartEvent, parent id 4 (active) 322 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 323 | 15:54:38.310 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.TakeOutgoingSequenceFlowsOperation : 324 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 325 | 15:54:38.311 [main] [INFO] 326 | 4 (process instance) 327 | └── 5 : start (StartEvent, parent id 4 (active) 328 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 329 | 15:54:38.312 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.ContinueProcessOperation : 330 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 331 | 15:54:38.312 [main] [INFO] 332 | 4 (process instance) 333 | └── 5 : start -> someTask, parent id 4 (active) 334 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 335 | 15:54:38.313 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.ContinueProcessOperation : 336 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 337 | 15:54:38.313 [main] [INFO] 338 | 4 (process instance) 339 | └── 5 : someTask (UserTask, parent id 4 (active) 340 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 341 | 15:54:38.389 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.TriggerExecutionOperation : 342 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 343 | 15:54:38.391 [main] [INFO] 344 | 4 (process instance) 345 | └── 5 : someTask (UserTask, parent id 4 (active) 346 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 347 | 15:54:38.392 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.TakeOutgoingSequenceFlowsOperation : 348 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 349 | 15:54:38.392 [main] [INFO] 350 | 4 (process instance) 351 | └── 5 : someTask (UserTask, parent id 4 (active) 352 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 353 | 15:54:38.393 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.ContinueProcessOperation : 354 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 355 | 15:54:38.394 [main] [INFO] 356 | 4 (process instance) 357 | └── 5 : someTask -> end, parent id 4 (active) 358 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 359 | 15:54:38.394 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.ContinueProcessOperation : 360 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 361 | 15:54:38.394 [main] [INFO] 362 | 4 (process instance) 363 | └── 5 : end (EndEvent, parent id 4 (active) 364 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 365 | 15:54:38.394 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.TakeOutgoingSequenceFlowsOperation : 366 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 367 | 15:54:38.395 [main] [INFO] 368 | 4 (process instance) 369 | └── 5 : end (EndEvent, parent id 4 (active) 370 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 371 | 15:54:38.396 [main] [INFO] Execution tree while executing operation class org.activiti.engine.impl.agenda.EndExecutionOperation : 372 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:33 373 | 15:54:38.396 [main] [INFO] 374 | 4 (process instance) 375 | └── 5 : end (EndEvent, parent id 4 (active) 376 | ProcessDefinitionId=my-process:1:3 executionId=5 mdcProcessInstanceId= mdcBusinessKey= o.a.e.i.i.DebugCommandInvoker.executeOperation:34 377 | 378 | Process finished with exit code 0 379 | 380 | ``` 381 | 382 | 383 | ### 4-8 历史记录配置-history-1 384 | ### 4-9 历史记录配置-history-2 385 | ### 4-10 事件处理及监听器配置-eventlog 386 | ### 4-11 事件处理及监听器配置-eventLinstener-1 387 | ### 4-12 事件处理及监听器配置-eventLinstener-2 388 | ### 4-13 命令拦截器配置-command-1 389 | ### 4-14 命令拦截器配置-command-2 390 | ### 4-15 作业执行器配置-job-1 391 | ### 4-16 作业执行器配置-job-2 392 | ### 4-17 Activiti与spring集成-1 393 | ### 4-18 Activiti与spring集成-2 394 | ### 4-19 Activiti与spring集成-3 395 | 396 | ## 参考网站: 397 | 398 | 1. [fhqscfss/activiti-test](https://github.com/fhqscfss/activiti-test) 399 | 2. [chandler1142/activiti-study](https://github.com/chandler1142/activiti-study) 400 | 3. [shengjie8329/activiti-helloword](https://github.com/shengjie8329/activiti-helloword) 401 | 4. [DestinyWang/activiti-sample](https://github.com/DestinyWang/activiti-sample) -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | org.activiti 5 | activiti-archetype-unittest2 6 | 6.0.0 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/META-INF/maven/archetype-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | src/main/java 7 | 8 | **/*.java 9 | 10 | 11 | 12 | src/main/resources 13 | 14 | activiti.cfg.xml 15 | logback.xml 16 | second_approve.bpmn 17 | 18 | 19 | 20 | src/test/java 21 | 22 | **/*.java 23 | 24 | 25 | 26 | src/test/resources 27 | 28 | activiti.cfg.xml 29 | log4j.properties 30 | my-process.bpmn20.xml 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | ${groupId} 5 | ${artifactId} 6 | ${version} 7 | jar 8 | ${artifactId} 9 | 10 | 11 | org.activiti 12 | activiti-engine 13 | 6.0.0 14 | 15 | 16 | junit 17 | junit 18 | 4.12 19 | test 20 | 21 | 22 | ch.qos.logback 23 | logback-classic 24 | 1.1.11 25 | 26 | 27 | com.google.guava 28 | guava 29 | 23.0 30 | 31 | 32 | com.h2database 33 | h2 34 | 1.3.176 35 | 36 | 37 | 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-compiler-plugin 43 | 3.6.1 44 | 45 | 1.8 46 | 1.8 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-resources-plugin 52 | 2.6 53 | 54 | UTF-8 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/src/main/java/DemoMain.java: -------------------------------------------------------------------------------- 1 | package ${package}; 2 | 3 | import com.google.common.collect.Maps; 4 | import org.activiti.engine.*; 5 | import org.activiti.engine.form.FormProperty; 6 | import org.activiti.engine.form.TaskFormData; 7 | import org.activiti.engine.impl.form.DateFormType; 8 | import org.activiti.engine.impl.form.StringFormType; 9 | import org.activiti.engine.repository.Deployment; 10 | import org.activiti.engine.repository.DeploymentBuilder; 11 | import org.activiti.engine.repository.ProcessDefinition; 12 | import org.activiti.engine.runtime.ProcessInstance; 13 | import org.activiti.engine.task.Task; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | import java.text.ParseException; 18 | import java.text.SimpleDateFormat; 19 | import java.util.Date; 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.Scanner; 23 | 24 | public class DemoMain { 25 | 26 | /** 27 | * logger 28 | */ 29 | private static final Logger LOGGER = LoggerFactory.getLogger(DemoMain.class); 30 | 31 | public static void main(String[] args) throws ParseException { 32 | LOGGER.info("启动我们的程序"); 33 | // 创建流程引擎 34 | ProcessEngine processEngine = getProcessEngine(); 35 | 36 | // 部署流程定义文件 37 | ProcessDefinition processDefinition = getProcessDefinition(processEngine); 38 | 39 | // 启动运行流程 40 | ProcessInstance processInstance = getProcessInstance(processEngine, processDefinition); 41 | 42 | // 处理流程任务 43 | processTask(processEngine, processInstance); 44 | 45 | LOGGER.info("结束我们的程序"); 46 | } 47 | 48 | private static void processTask(ProcessEngine processEngine, ProcessInstance processInstance) throws ParseException { 49 | Scanner scanner = new Scanner(System.in); 50 | while (processInstance != null && !processInstance.isEnded()) { 51 | TaskService taskService = processEngine.getTaskService(); 52 | List list = taskService.createTaskQuery().list(); 53 | LOGGER.info("待处理任务数量 [{}]", list.size()); 54 | for (Task task : list) { 55 | LOGGER.info("待处理任务 [{}]", task.getName()); 56 | Map variables = getMap(processEngine, scanner, task); 57 | 58 | // 提交工作 59 | taskService.complete(task.getId(), variables); 60 | // 同步流程状态 61 | processInstance = processEngine 62 | .getRuntimeService() 63 | .createProcessInstanceQuery() 64 | .processInstanceId(processInstance.getId()) 65 | .singleResult(); 66 | } 67 | } 68 | scanner.close(); 69 | } 70 | 71 | private static Map getMap(ProcessEngine processEngine, Scanner scanner, Task task) throws ParseException { 72 | FormService formService = processEngine.getFormService(); 73 | TaskFormData taskFormData = formService.getTaskFormData(task.getId()); 74 | List formProperties = taskFormData.getFormProperties(); 75 | Map variables = Maps.newHashMap(); 76 | for (FormProperty property : formProperties) { 77 | String line = null; 78 | if (StringFormType.class.isInstance(property.getType())) { 79 | LOGGER.info("请输入 {} ?", property.getName()); 80 | line = scanner.nextLine(); 81 | variables.put(property.getId(), line); 82 | } else if (DateFormType.class.isInstance(property.getType())) { 83 | LOGGER.info("请输入 {} ? 格式 (yyyy-MM-dd)", property.getName()); 84 | line = scanner.nextLine(); 85 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 86 | Date date = dateFormat.parse(line); 87 | variables.put(property.getId(), date); 88 | } else { 89 | LOGGER.info("类型暂不支持 [{}] ", property.getType()); 90 | } 91 | LOGGER.info("您输入的内容是 [{}] :", line); 92 | } 93 | return variables; 94 | } 95 | 96 | private static ProcessInstance getProcessInstance(ProcessEngine processEngine, ProcessDefinition processDefinition) { 97 | RuntimeService runtimeService = processEngine.getRuntimeService(); 98 | ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId()); 99 | LOGGER.info("启动流程 [{}]", processInstance.getProcessDefinitionKey()); 100 | return processInstance; 101 | } 102 | 103 | private static ProcessDefinition getProcessDefinition(ProcessEngine processEngine) { 104 | RepositoryService repositoryService = processEngine.getRepositoryService(); 105 | DeploymentBuilder deploymentBuilder = repositoryService.createDeployment(); 106 | deploymentBuilder.addClasspathResource("second_approve.bpmn"); 107 | Deployment deployment = deploymentBuilder.deploy(); 108 | String deploymentId = deployment.getId(); 109 | ProcessDefinition processDefinition = repositoryService 110 | .createProcessDefinitionQuery() 111 | .deploymentId(deploymentId) 112 | .singleResult(); 113 | LOGGER.info("流程定义文件 [{}],流程ID [{}]", processDefinition.getName(), processDefinition.getId()); 114 | return processDefinition; 115 | } 116 | 117 | private static ProcessEngine getProcessEngine() { 118 | ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration(); 119 | ProcessEngine processEngine = cfg.buildProcessEngine(); 120 | String name = processEngine.getName(); 121 | String version = ProcessEngine.VERSION; 122 | LOGGER.info("流程引擎名称{},版本{}", name, version); 123 | return processEngine; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/src/main/resources/activiti.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ${plain} 12 | ${encoding} 13 | 14 | 15 | 16 | 17 | 19 | ${log.dir}/file.log 20 | 21 | ${log.dir}/file.%d{yyyy-MM-dd}.log 22 | 30 23 | 24 | 25 | ${std} 26 | ${encoding} 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/src/main/resources/second_approve.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/src/test/java/MyUnitTest.java: -------------------------------------------------------------------------------- 1 | package ${package}; 2 | import org.activiti.engine.runtime.ProcessInstance; 3 | import org.activiti.engine.task.Task; 4 | import org.activiti.engine.test.ActivitiRule; 5 | import org.activiti.engine.test.Deployment; 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | 9 | import static org.junit.Assert.*; 10 | 11 | public class MyUnitTest { 12 | 13 | @Rule 14 | public ActivitiRule activitiRule = new ActivitiRule(); 15 | 16 | @Test 17 | @Deployment(resources = {"my-process.bpmn20.xml"}) 18 | public void test() { 19 | ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process"); 20 | assertNotNull(processInstance); 21 | 22 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 23 | assertEquals("Activiti is awesome!", task.getName()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/src/test/resources/activiti.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, CA 2 | 3 | # ConsoleAppender 4 | log4j.appender.CA=org.apache.log4j.ConsoleAppender 5 | log4j.appender.CA.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n 7 | 8 | 9 | log4j.logger.org.apache.ibatis.level=INFO 10 | log4j.logger.javax.activation.level=INFO 11 | -------------------------------------------------------------------------------- /Chapter04/activiti-archetype-unittest2/src/main/resources/archetype-resources/src/test/resources/my-process.bpmn20.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | activiti6-samples 5 | com.coderdream 6 | 1.0-SNAPSHOT 7 | 8 | 4.0.0 9 | config 10 | jar 11 | config 12 | 13 | 14 | org.activiti 15 | activiti-engine 16 | 6.0.0 17 | 18 | 19 | junit 20 | junit 21 | 4.12 22 | test 23 | 24 | 25 | ch.qos.logback 26 | logback-classic 27 | 1.1.11 28 | 29 | 30 | com.google.guava 31 | guava 32 | 23.0 33 | 34 | 35 | com.h2database 36 | h2 37 | 1.3.176 38 | 39 | 40 | org.activiti 41 | activiti-spring 42 | 6.0.0 43 | 44 | 45 | mysql 46 | mysql-connector-java 47 | 5.1.47 48 | 49 | 50 | com.alibaba 51 | druid 52 | 1.1.6 53 | 54 | 55 | 56 | 57 | 58 | 59 | org.apache.maven.plugins 60 | maven-compiler-plugin 61 | 3.6.1 62 | 63 | 1.8 64 | 1.8 65 | 66 | 67 | 68 | org.apache.maven.plugins 69 | maven-resources-plugin 70 | 2.6 71 | 72 | UTF-8 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/java/com/coderdream/DemoMain.java: -------------------------------------------------------------------------------- 1 | package com.coderdream; 2 | 3 | import com.google.common.collect.Maps; 4 | import org.activiti.engine.*; 5 | import org.activiti.engine.form.FormProperty; 6 | import org.activiti.engine.form.TaskFormData; 7 | import org.activiti.engine.impl.form.DateFormType; 8 | import org.activiti.engine.impl.form.StringFormType; 9 | import org.activiti.engine.repository.Deployment; 10 | import org.activiti.engine.repository.DeploymentBuilder; 11 | import org.activiti.engine.repository.ProcessDefinition; 12 | import org.activiti.engine.runtime.ProcessInstance; 13 | import org.activiti.engine.task.Task; 14 | import org.slf4j.Logger; 15 | import org.slf4j.LoggerFactory; 16 | 17 | import java.text.ParseException; 18 | import java.text.SimpleDateFormat; 19 | import java.util.Date; 20 | import java.util.List; 21 | import java.util.Map; 22 | import java.util.Scanner; 23 | 24 | public class DemoMain { 25 | 26 | /** 27 | * logger 28 | */ 29 | private static final Logger LOGGER = LoggerFactory.getLogger(DemoMain.class); 30 | 31 | public static void main(String[] args) throws ParseException { 32 | LOGGER.info("启动我们的程序"); 33 | // 创建流程引擎 34 | ProcessEngine processEngine = getProcessEngine(); 35 | 36 | // 部署流程定义文件 37 | ProcessDefinition processDefinition = getProcessDefinition(processEngine); 38 | 39 | // 启动运行流程 40 | ProcessInstance processInstance = getProcessInstance(processEngine, processDefinition); 41 | 42 | // 处理流程任务 43 | processTask(processEngine, processInstance); 44 | 45 | LOGGER.info("结束我们的程序"); 46 | } 47 | 48 | private static void processTask(ProcessEngine processEngine, ProcessInstance processInstance) throws ParseException { 49 | Scanner scanner = new Scanner(System.in); 50 | while (processInstance != null && !processInstance.isEnded()) { 51 | TaskService taskService = processEngine.getTaskService(); 52 | List list = taskService.createTaskQuery().list(); 53 | LOGGER.info("待处理任务数量 [{}]", list.size()); 54 | for (Task task : list) { 55 | LOGGER.info("待处理任务 [{}]", task.getName()); 56 | Map variables = getMap(processEngine, scanner, task); 57 | 58 | // 提交工作 59 | taskService.complete(task.getId(), variables); 60 | // 同步流程状态 61 | processInstance = processEngine 62 | .getRuntimeService() 63 | .createProcessInstanceQuery() 64 | .processInstanceId(processInstance.getId()) 65 | .singleResult(); 66 | } 67 | } 68 | scanner.close(); 69 | } 70 | 71 | private static Map getMap(ProcessEngine processEngine, Scanner scanner, Task task) throws ParseException { 72 | FormService formService = processEngine.getFormService(); 73 | TaskFormData taskFormData = formService.getTaskFormData(task.getId()); 74 | List formProperties = taskFormData.getFormProperties(); 75 | Map variables = Maps.newHashMap(); 76 | for (FormProperty property : formProperties) { 77 | String line = null; 78 | if (StringFormType.class.isInstance(property.getType())) { 79 | LOGGER.info("请输入 {} ?", property.getName()); 80 | line = scanner.nextLine(); 81 | variables.put(property.getId(), line); 82 | } else if (DateFormType.class.isInstance(property.getType())) { 83 | LOGGER.info("请输入 {} ? 格式 (yyyy-MM-dd)", property.getName()); 84 | line = scanner.nextLine(); 85 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 86 | Date date = dateFormat.parse(line); 87 | variables.put(property.getId(), date); 88 | } else { 89 | LOGGER.info("类型暂不支持 [{}] ", property.getType()); 90 | } 91 | LOGGER.info("您输入的内容是 [{}] :", line); 92 | } 93 | return variables; 94 | } 95 | 96 | private static ProcessInstance getProcessInstance(ProcessEngine processEngine, ProcessDefinition processDefinition) { 97 | RuntimeService runtimeService = processEngine.getRuntimeService(); 98 | ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId()); 99 | LOGGER.info("启动流程 [{}]", processInstance.getProcessDefinitionKey()); 100 | return processInstance; 101 | } 102 | 103 | private static ProcessDefinition getProcessDefinition(ProcessEngine processEngine) { 104 | RepositoryService repositoryService = processEngine.getRepositoryService(); 105 | DeploymentBuilder deploymentBuilder = repositoryService.createDeployment(); 106 | deploymentBuilder.addClasspathResource("second_approve.bpmn"); 107 | Deployment deployment = deploymentBuilder.deploy(); 108 | String deploymentId = deployment.getId(); 109 | ProcessDefinition processDefinition = repositoryService 110 | .createProcessDefinitionQuery() 111 | .deploymentId(deploymentId) 112 | .singleResult(); 113 | LOGGER.info("流程定义文件 [{}],流程ID [{}]", processDefinition.getName(), processDefinition.getId()); 114 | return processDefinition; 115 | } 116 | 117 | private static ProcessEngine getProcessEngine() { 118 | ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration(); 119 | ProcessEngine processEngine = cfg.buildProcessEngine(); 120 | String name = processEngine.getName(); 121 | String version = ProcessEngine.VERSION; 122 | LOGGER.info("流程引擎名称{},版本{}", name, version); 123 | return processEngine; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/java/com/coderdream/delegate/MDCErrorDelegate.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.delegate; 2 | 3 | import org.activiti.engine.delegate.DelegateExecution; 4 | import org.activiti.engine.delegate.JavaDelegate; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class MDCErrorDelegate implements JavaDelegate { 9 | 10 | /** logger */ 11 | private static final Logger LOGGER = LoggerFactory.getLogger(MDCErrorDelegate.class); 12 | 13 | @Override 14 | public void execute(DelegateExecution execution) { 15 | LOGGER.info("run MDCErrorDelegate"); 16 | throw new RuntimeException("only test"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/java/com/coderdream/event/CustomEventListener.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.event; 2 | 3 | import org.activiti.engine.delegate.event.ActivitiEvent; 4 | import org.activiti.engine.delegate.event.ActivitiEventListener; 5 | import org.activiti.engine.delegate.event.ActivitiEventType; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class CustomEventListener implements ActivitiEventListener { 10 | 11 | /** logger */ 12 | private static final Logger LOGGER = LoggerFactory.getLogger(CustomEventListener.class); 13 | 14 | @Override 15 | public void onEvent(ActivitiEvent event) { 16 | ActivitiEventType eventType = event.getType(); 17 | 18 | if(ActivitiEventType.CUSTOM.equals(eventType)) { 19 | LOGGER.info("监听到自定义事件 {} \t {}", eventType, event.getProcessInstanceId()); 20 | } 21 | } 22 | 23 | @Override 24 | public boolean isFailOnException() { 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/java/com/coderdream/event/ProcessEventListener.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.event; 2 | 3 | import org.activiti.engine.delegate.event.ActivitiEvent; 4 | import org.activiti.engine.delegate.event.ActivitiEventListener; 5 | import org.activiti.engine.delegate.event.ActivitiEventType; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class ProcessEventListener implements ActivitiEventListener { 10 | 11 | /** logger */ 12 | private static final Logger LOGGER = LoggerFactory.getLogger(ProcessEventListener.class); 13 | 14 | @Override 15 | public void onEvent(ActivitiEvent event) { 16 | ActivitiEventType eventType = event.getType(); 17 | 18 | if(ActivitiEventType.PROCESS_STARTED.equals(eventType)) { 19 | LOGGER.info("流程启动 {} \t {}", eventType, event.getProcessInstanceId()); 20 | } else if(ActivitiEventType.PROCESS_COMPLETED.equals(eventType)) { 21 | LOGGER.info("流程结束 {} \t {}", eventType, event.getProcessInstanceId()); 22 | } 23 | } 24 | 25 | @Override 26 | public boolean isFailOnException() { 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/java/com/coderdream/interceptor/MDCCommandInvoker.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.interceptor; 2 | 3 | import org.activiti.engine.impl.agenda.AbstractOperation; 4 | import org.activiti.engine.impl.interceptor.DebugCommandInvoker; 5 | import org.activiti.engine.logging.LogMDC; 6 | 7 | public class MDCCommandInvoker extends DebugCommandInvoker { 8 | 9 | // 参考DebugCommandInvoker代码 10 | @Override 11 | public void executeOperation(Runnable runnable) { 12 | // 保存默认状态 13 | boolean mdcEnabled = LogMDC.isMDCEnabled(); 14 | // 修改状态 15 | LogMDC.setMDCEnabled(true); 16 | if (runnable instanceof AbstractOperation) { 17 | AbstractOperation operation = (AbstractOperation) runnable; 18 | 19 | if (operation.getExecution() != null) { 20 | // 记录日志 21 | LogMDC.putMDCExecution(operation.getExecution()); 22 | } 23 | 24 | } 25 | 26 | super.executeOperation(runnable); 27 | // 清理上下文信息 28 | LogMDC.clear(); 29 | // 还原为默认状态 30 | if (!mdcEnabled) { 31 | LogMDC.setMDCEnabled(false); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/resources/activiti.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/resources/activiti_druid.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/resources/activiti_eventListener.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/resources/activiti_eventlog.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/resources/activiti_history.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/resources/activiti_mdc.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 18 | 19 | 20 | 21 | 22 | ${mdc} 23 | ${encoding} 24 | 25 | 26 | 27 | 28 | 30 | ${log.dir}/file.log 31 | 32 | ${log.dir}/file.%d{yyyy-MM-dd}.log 33 | 30 34 | 35 | 36 | ${std} 37 | ${encoding} 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/main/resources/second_approve.bpmn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/java/com/coderdream/MyUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.coderdream; 2 | import org.activiti.engine.runtime.ProcessInstance; 3 | import org.activiti.engine.task.Task; 4 | import org.activiti.engine.test.ActivitiRule; 5 | import org.activiti.engine.test.Deployment; 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | 9 | import static org.junit.Assert.*; 10 | 11 | public class MyUnitTest { 12 | 13 | @Rule 14 | public ActivitiRule activitiRule = new ActivitiRule(); 15 | 16 | @Test 17 | @Deployment(resources = {"my-process.bpmn20.xml"}) 18 | public void test() { 19 | ProcessInstance processInstance = activitiRule.getRuntimeService().startProcessInstanceByKey("my-process"); 20 | assertNotNull(processInstance); 21 | 22 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 23 | assertEquals("Activiti is awesome!", task.getName()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/java/com/coderdream/config/ConfigEventListenerTest.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.config; 2 | 3 | import com.coderdream.event.CustomEventListener; 4 | import org.activiti.engine.delegate.event.ActivitiEventType; 5 | import org.activiti.engine.delegate.event.impl.ActivitiEventImpl; 6 | import org.activiti.engine.event.EventLogEntry; 7 | import org.activiti.engine.runtime.ProcessInstance; 8 | import org.activiti.engine.task.Task; 9 | import org.activiti.engine.test.ActivitiRule; 10 | import org.activiti.engine.test.Deployment; 11 | import org.junit.Rule; 12 | import org.junit.Test; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import java.util.List; 17 | 18 | public class ConfigEventListenerTest { 19 | 20 | /** logger */ 21 | private static final Logger LOGGER = LoggerFactory.getLogger(ConfigEventListenerTest.class); 22 | 23 | @Rule 24 | public ActivitiRule activitiRule = new ActivitiRule("activiti_eventListener.cfg.xml"); 25 | 26 | @Test 27 | @Deployment(resources = {"my-process.bpmn20.xml"}) 28 | public void test() { 29 | ProcessInstance processInstance = activitiRule.getRuntimeService() 30 | .startProcessInstanceByKey("my-process"); 31 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 32 | // 继续执行流程 33 | activitiRule.getTaskService().complete(task.getId()); 34 | // 通过代码添加监听器(非配置文件方式) 35 | activitiRule.getRuntimeService().addEventListener(new CustomEventListener()); 36 | // 添加一个自定义事件 37 | activitiRule.getRuntimeService().dispatchEvent(new ActivitiEventImpl(ActivitiEventType.CUSTOM)); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/java/com/coderdream/config/ConfigEventLogTest.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.config; 2 | 3 | import org.activiti.engine.event.EventLogEntry; 4 | import org.activiti.engine.logging.LogMDC; 5 | import org.activiti.engine.runtime.ProcessInstance; 6 | import org.activiti.engine.task.Task; 7 | import org.activiti.engine.test.ActivitiRule; 8 | import org.activiti.engine.test.Deployment; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.util.List; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertNotNull; 18 | 19 | public class ConfigEventLogTest { 20 | 21 | /** logger */ 22 | private static final Logger LOGGER = LoggerFactory.getLogger(ConfigEventLogTest.class); 23 | 24 | @Rule 25 | public ActivitiRule activitiRule = new ActivitiRule("activiti_eventlog.cfg.xml"); 26 | 27 | @Test 28 | @Deployment(resources = {"my-process.bpmn20.xml"}) 29 | public void test() { 30 | ProcessInstance processInstance = activitiRule.getRuntimeService() 31 | .startProcessInstanceByKey("my-process"); 32 | 33 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 34 | 35 | // 继续执行流程 36 | activitiRule.getTaskService().complete(task.getId()); 37 | 38 | 39 | List eventLogEntries = activitiRule.getManagementService() 40 | .getEventLogEntriesByProcessInstanceId(processInstance.getProcessInstanceId()); 41 | for (EventLogEntry eventLogEntry : eventLogEntries) { 42 | LOGGER.info("eventLogEntry = {}, eventLog.data = {}", eventLogEntry, new String(eventLogEntry.getData())); 43 | } 44 | LOGGER.info("eventLogEntries.size = {}", eventLogEntries.size()); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/java/com/coderdream/config/ConfigHistoryLevelTest.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.config; 2 | 3 | import com.google.common.collect.Maps; 4 | import org.activiti.engine.history.HistoricActivityInstance; 5 | import org.activiti.engine.history.HistoricDetail; 6 | import org.activiti.engine.history.HistoricTaskInstance; 7 | import org.activiti.engine.history.HistoricVariableInstance; 8 | import org.activiti.engine.logging.LogMDC; 9 | import org.activiti.engine.runtime.Execution; 10 | import org.activiti.engine.runtime.ProcessInstance; 11 | import org.activiti.engine.task.Task; 12 | import org.activiti.engine.test.ActivitiRule; 13 | import org.activiti.engine.test.Deployment; 14 | import org.apache.commons.lang3.builder.ToStringBuilder; 15 | import org.apache.commons.lang3.builder.ToStringStyle; 16 | import org.junit.Rule; 17 | import org.junit.Test; 18 | import org.slf4j.Logger; 19 | import org.slf4j.LoggerFactory; 20 | 21 | import java.util.List; 22 | import java.util.Map; 23 | 24 | import static org.junit.Assert.assertEquals; 25 | import static org.junit.Assert.assertNotNull; 26 | 27 | public class ConfigHistoryLevelTest { 28 | 29 | /** logger */ 30 | private static final Logger LOGGER = LoggerFactory.getLogger(ConfigHistoryLevelTest.class); 31 | 32 | @Rule 33 | public ActivitiRule activitiRule = new ActivitiRule("activiti_history.cfg.xml"); 34 | 35 | @Test 36 | @Deployment(resources = {"my-process.bpmn20.xml"}) 37 | public void test() { 38 | // 1. 启动流程 39 | Map params = Maps.newHashMap(); 40 | params.put("keyStart1", "value1"); 41 | params.put("keyStart2", "value2"); 42 | ProcessInstance processInstance = activitiRule.getRuntimeService() 43 | .startProcessInstanceByKey("my-process", params); 44 | 45 | // 2. 修改变量 46 | List executions = activitiRule.getRuntimeService() 47 | .createExecutionQuery().listPage(0, 100); 48 | 49 | for (Execution execution : executions) { 50 | LOGGER.info("execution = {}", execution); 51 | } 52 | LOGGER.info("executions.size = {}", executions.size()); 53 | 54 | // 取第一条记录 55 | String id = executions.iterator().next().getId(); 56 | activitiRule.getRuntimeService().setVariable(id, "keyStart1", "value1_"); 57 | 58 | // 3. 提交表单 task 59 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 60 | Map properties = Maps.newHashMap(); 61 | properties.put("formKey1", "valuef1"); 62 | properties.put("formKey2", "valuef2"); 63 | activitiRule.getFormService().submitTaskFormData(task.getId(), properties); 64 | assertEquals("Activiti is awesome!", task.getName()); 65 | 66 | // 4. 输出历史内容 67 | // 4.1. 输出历史活动 68 | List historicActivityInstances = activitiRule.getHistoryService(). 69 | createHistoricActivityInstanceQuery().listPage(0,100); 70 | for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { 71 | LOGGER.info("historicActivityInstance = {}", historicActivityInstance); 72 | } 73 | LOGGER.info("historicActivityInstances.size = {}", historicActivityInstances.size()); 74 | 75 | // 4.2 输出历史变量 76 | List historicVariableInstances = activitiRule.getHistoryService() 77 | .createHistoricVariableInstanceQuery().listPage(0, 100); 78 | for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) { 79 | LOGGER.info("historicVariableInstance = {}", historicVariableInstance); 80 | } 81 | LOGGER.info("historicVariableInstances.size = {}", historicVariableInstances.size()); 82 | 83 | // 4.3. 输出历史表单 84 | List historicTaskInstances = activitiRule.getHistoryService() 85 | .createHistoricTaskInstanceQuery().listPage(0,100); 86 | for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) { 87 | LOGGER.info("historicTaskInstance = {}", historicTaskInstance); 88 | } 89 | LOGGER.info("historicTaskInstances.size = {}", historicTaskInstances.size()); 90 | 91 | // 4.4. 输出历史表单详情 92 | List historicDetailsForm = activitiRule.getHistoryService(). 93 | createHistoricDetailQuery().formProperties().listPage(0,100); 94 | 95 | for (HistoricDetail historicDetail : historicDetailsForm) { 96 | LOGGER.info("historicDetail = {}", historicDetail); 97 | } 98 | LOGGER.info("historicDetailsForm.size = {}", historicDetailsForm.size()); 99 | 100 | // 4.5. 输出历史详情 101 | List historicDetails = activitiRule.getHistoryService(). 102 | createHistoricDetailQuery().listPage(0,100); 103 | 104 | for (HistoricDetail historicDetail : historicDetails) { 105 | LOGGER.info("historicDetail = {}", toString(historicDetail)); 106 | } 107 | LOGGER.info("historicDetails.size = {}", historicDetails.size()); 108 | } 109 | 110 | static String toString(HistoricDetail historicDetail) { 111 | return ToStringBuilder.reflectionToString(historicDetail, ToStringStyle.SHORT_PREFIX_STYLE); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/java/com/coderdream/config/ConfigMDCTest.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.config; 2 | 3 | import org.activiti.engine.logging.LogMDC; 4 | import org.activiti.engine.runtime.ProcessInstance; 5 | import org.activiti.engine.task.Task; 6 | import org.activiti.engine.test.ActivitiRule; 7 | import org.activiti.engine.test.Deployment; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import static org.junit.Assert.assertEquals; 14 | import static org.junit.Assert.assertNotNull; 15 | 16 | public class ConfigMDCTest { 17 | 18 | /** logger */ 19 | private static final Logger LOGGER = LoggerFactory.getLogger(ConfigMDCTest.class); 20 | 21 | @Rule 22 | public ActivitiRule activitiRule = new ActivitiRule("activiti_mdc.cfg.xml"); 23 | 24 | @Test 25 | @Deployment(resources = {"my-process.bpmn20.xml"}) 26 | public void test() { 27 | // 打开MDC开关 28 | LogMDC.setMDCEnabled(true); 29 | ProcessInstance processInstance = activitiRule.getRuntimeService() 30 | .startProcessInstanceByKey("my-process"); 31 | assertNotNull(processInstance); 32 | 33 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 34 | assertEquals("Activiti is awesome!", task.getName()); 35 | 36 | // 继续执行流程 37 | activitiRule.getTaskService().complete(task.getId()); 38 | } 39 | 40 | @Test 41 | @Deployment(resources = {"my-process_mdcerror.bpmn20.xml"}) 42 | public void test2() { 43 | ProcessInstance processInstance = activitiRule.getRuntimeService() 44 | .startProcessInstanceByKey("my-process"); 45 | assertNotNull(processInstance); 46 | 47 | Task task = activitiRule.getTaskService().createTaskQuery().singleResult(); 48 | assertEquals("Activiti is awesome!", task.getName()); 49 | 50 | // 继续执行流程 51 | activitiRule.getTaskService().complete(task.getId()); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/java/com/coderdream/config/ConfigTest.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.config; 2 | 3 | 4 | import org.activiti.engine.ProcessEngineConfiguration; 5 | import org.junit.Test; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class ConfigTest { 10 | 11 | /** 12 | * logger 13 | */ 14 | private static final Logger LOGGER = LoggerFactory.getLogger(ConfigTest.class); 15 | 16 | @Test 17 | public void testConfig1() { 18 | ProcessEngineConfiguration configuration = ProcessEngineConfiguration 19 | .createProcessEngineConfigurationFromResourceDefault(); 20 | 21 | LOGGER.info("configuration = {}", configuration); 22 | } 23 | 24 | @Test 25 | public void testConfig2() { 26 | ProcessEngineConfiguration configuration = ProcessEngineConfiguration 27 | .createStandaloneProcessEngineConfiguration(); 28 | 29 | LOGGER.info("configuration = {}", configuration); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/java/com/coderdream/config/ConfitDBTest.java: -------------------------------------------------------------------------------- 1 | package com.coderdream.config; 2 | 3 | import org.activiti.engine.ProcessEngine; 4 | import org.activiti.engine.ProcessEngineConfiguration; 5 | import org.junit.Test; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class ConfitDBTest { 10 | 11 | /** logger */ 12 | private static final Logger LOGGER = LoggerFactory.getLogger(ConfitDBTest.class); 13 | 14 | @Test 15 | public void testConfig1() { 16 | ProcessEngineConfiguration configuration = ProcessEngineConfiguration 17 | .createProcessEngineConfigurationFromResourceDefault(); 18 | 19 | LOGGER.info("configuration = {}", configuration); 20 | ProcessEngine processEngine = configuration.buildProcessEngine(); 21 | LOGGER.info("获取流程引擎 {}", processEngine.getName()); 22 | processEngine.close(); 23 | } 24 | 25 | @Test 26 | public void testConfig2() { 27 | ProcessEngineConfiguration configuration = ProcessEngineConfiguration 28 | .createProcessEngineConfigurationFromResource("activiti_druid.cfg.xml"); 29 | 30 | LOGGER.info("configuration = {}", configuration); 31 | ProcessEngine processEngine = configuration.buildProcessEngine(); 32 | LOGGER.info("获取流程引擎 {}", processEngine.getName()); 33 | processEngine.close(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/resources/activiti.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, CA 2 | 3 | # ConsoleAppender 4 | log4j.appender.CA=org.apache.log4j.ConsoleAppender 5 | log4j.appender.CA.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n 7 | 8 | 9 | log4j.logger.org.apache.ibatis.level=INFO 10 | log4j.logger.javax.activation.level=INFO 11 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/resources/my-process.bpmn20.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/config/src/test/resources/my-process_mdcerror.bpmn20.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter04/activiti6-samples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.coderdream 8 | activiti6-samples 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | config 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-starter-parent 18 | 2.0.0.RELEASE 19 | 20 | 21 | -------------------------------------------------------------------------------- /Chapter04/images/0401_Project_Structrue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0401_Project_Structrue.png -------------------------------------------------------------------------------- /Chapter04/images/0402_Add_Archetype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0402_Add_Archetype.png -------------------------------------------------------------------------------- /Chapter04/images/0403_Create_From_Archetype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0403_Create_From_Archetype.png -------------------------------------------------------------------------------- /Chapter04/images/0404_ProcessEngineConfiguration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0404_ProcessEngineConfiguration.png -------------------------------------------------------------------------------- /Chapter04/images/0406_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0406_01.jpg -------------------------------------------------------------------------------- /Chapter04/images/0406_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0406_02.jpg -------------------------------------------------------------------------------- /Chapter04/images/0406_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0406_03.jpg -------------------------------------------------------------------------------- /Chapter04/images/0406_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0406_04.jpg -------------------------------------------------------------------------------- /Chapter04/images/0406_05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0406_05.jpg -------------------------------------------------------------------------------- /Chapter04/images/0406_06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/0406_06.jpg -------------------------------------------------------------------------------- /Chapter04/images/041000_Result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041000_Result.png -------------------------------------------------------------------------------- /Chapter04/images/041001_ProcessEngineConfigurationImpl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041001_ProcessEngineConfigurationImpl.png -------------------------------------------------------------------------------- /Chapter04/images/041002_initDatabaseEventLogging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041002_initDatabaseEventLogging.png -------------------------------------------------------------------------------- /Chapter04/images/041003_EventLogger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041003_EventLogger.png -------------------------------------------------------------------------------- /Chapter04/images/041004_addCloseListener.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041004_addCloseListener.png -------------------------------------------------------------------------------- /Chapter04/images/041005_insert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041005_insert.png -------------------------------------------------------------------------------- /Chapter04/images/041101.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041101.jpg -------------------------------------------------------------------------------- /Chapter04/images/041102.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041102.jpg -------------------------------------------------------------------------------- /Chapter04/images/041103.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041103.jpg -------------------------------------------------------------------------------- /Chapter04/images/041104.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041104.jpg -------------------------------------------------------------------------------- /Chapter04/images/041105.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041105.jpg -------------------------------------------------------------------------------- /Chapter04/images/041201_ActivitiEventListener.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041201_ActivitiEventListener.png -------------------------------------------------------------------------------- /Chapter04/images/041202_BaseEntityEventListener.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041202_BaseEntityEventListener.png -------------------------------------------------------------------------------- /Chapter04/images/041203_ActivitiEvent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041203_ActivitiEvent.png -------------------------------------------------------------------------------- /Chapter04/images/041204_ActivitiEntityEvent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041204_ActivitiEntityEvent.png -------------------------------------------------------------------------------- /Chapter04/images/041205_ActivitiVariableEvent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDream/ActivitiInAction/97e80418cb1be68fcb7e522530dc96a02a6f2093/Chapter04/images/041205_ActivitiVariableEvent.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 CoderDream 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ActivitiInAction 2 | Activiti6.0工作流引擎深度解析与实战 3 | 章节 4 | ### 第1章 课程介绍 5 | - 1-1 课程导学 6 | ### 第2章 工作流入门 7 | - 2-1 本章概述 8 | - 2-2 工作流介绍 9 | - 2-3 工作流引擎技术选型 10 | - 2-4 Activiti6.0快速体验-部署环境介绍 11 | - 2-5 Activiti6.0快速体验-部署环境实操 12 | - 2-6 Activiti6.0快速体验-流程体验 13 | ### 第3章 Activiti6.0源码初探 14 | - 3-1 本章概述 15 | - 3-2 Activiti6.0源码初探-概览与获取 16 | - 3-3 Activiti6.0源码初探-engine 17 | - 3-4 Activiti6.0源码初探-模块介绍 18 | - 3-5 Activiti6.0源码初探-activiti-app运行 19 | - 3-6 Activiti6.0源码初探-WebConfigurer 20 | - 3-7 Activiti6.0源码初探-helloword-1 21 | - 3-8 Activiti6.0源码初探-helloword-2 22 | - 3-9 Activiti6.0源码初探-helloword_idea-1 23 | - 3-10 Activiti6.0源码初探-helloword_idea-2 24 | - 3-11 Activiti6.0源码初探-helloword_idea-3 25 | ### 第4章 Activiti6.0引擎配置 26 | - 4-1 本章概述 27 | - 4-2 创建流程引擎配置-config_samples 28 | - 4-3 创建流程引擎配置-archetype 29 | - 4-4 数据库配置-dbconfig 30 | - 4-5 数据库配置-dbconfig_code 31 | - 4-6 日志记录配置-logging 32 | - 4-7 日志记录配置-logging_mdc 33 | - 4-8 历史记录配置-history-1 34 | - [4-9 历史记录配置-history-2](/Chapter04/Chapter0410.md) 35 | - 4-10 事件处理及监听器配置-eventlog 36 | - 4-11 事件处理及监听器配置-eventLinstener-1 37 | - [4-12 事件处理及监听器配置-eventLinstener-2](/Chapter04/Chapter0410.md) 38 | - 4-13 命令拦截器配置-command-1 39 | - 4-14 命令拦截器配置-command-2 40 | - 4-15 作业执行器配置-job-1 41 | - 4-16 作业执行器配置-job-2 42 | - 4-17 Activiti与spring集成-1 43 | - 4-18 Activiti与spring集成-2 44 | - 4-19 Activiti与spring集成-3 45 | ### 第5章 Activiti核心API 46 | - 5-1 本章概述 47 | - 5-2 流程存储服务-RepositoryService-1 48 | - 5-3 流程存储服务-RepositoryService-2 49 | - 5-4 流程运行 控制服务-RuntimeService-1 50 | - 5-5 流程运行 控制服务-RuntimeService-2 51 | - 5-6 流程运行 控制服务-RuntimeService-3 52 | - 5-7 任务管理服务-TaskService-1 53 | - 5-8 任务管理服务-TaskService-2 54 | - 5-9 任务管理服务-TaskService-3 55 | - 5-10 用户和用户组管理服务-IdentityService 56 | - 5-11 表单管理服务- formeService 57 | - 5-12 历史数据管理服务-HistoryService-1 58 | - 5-13 历史数据管理服务-HistoryService-2 59 | - 5-14 其它管理服务-OtherService 60 | - 5-15 异常策略 61 | ### 第6章 数据库设计与模型映射 62 | - 6-1 通用数据表设计 63 | - 6-2 流程定义存储表设计 64 | - 6-3 身份数据表设计 65 | - 6-4 运行时流程数据表设计-1 66 | - 6-5 运行时流程数据表设计-2 67 | - 6-6 历史流程数据表设计-1 68 | - 6-7 历史流程数据表设计-2 69 | ### 第7章 BPMN2.0规范 70 | - 7-1 本章概述 71 | - 7-2 BPMN2.0流程事件-事件分类 72 | - 7-3 BPMN2.0流程事件-错误事件 73 | - 7-4 BPMN2.0流程事件-信号消息事件 74 | - 7-5 BPMN2.0流程任务-用户任务-1 75 | - 7-6 BPMN2.0流程任务-用户任务-2 76 | - 7-7 BPMN2.0脚本任务 77 | - 7-8 BPMN2.0服务任务-1 78 | - 7-9 BPMN2.0服务任务-2 79 | - 7-10 BPMN2.0顺序流和网关-1 80 | - 7-11 BPMN2.0顺序流和网关-2 81 | - 7-12 BPMN2.0顺序流和网关-3 82 | - 7-13 BPMN2.0子流程-1 83 | - 7-14 BPMN2.0子流程-2 84 | - 7-15 BPMN2.0子流程-3 85 | - 7-16 BPMN2.0子流程-4 86 | ### 第8章 Activiti6.0集成Spring Boot2.0 87 | - 8-1 本章概述 88 | - 8-2 Spring Boot2.0入门实例-1 89 | - 8-3 Spring Boot2.0入门实例-2 90 | - 8-4 Spring Boot2.0启动依赖和自动装配-1 91 | - 8-5 Spring Boot2.0启动依赖和自动装配-2 92 | - 8-6 Activiti6.0与Spring Boot2.0集成-1 93 | - 8-7 Activiti6.0与Spring Boot2.0集成-2 94 | ### 第9章 工作流平台搭建 95 | - 9-1 工作流平台搭建-需求分析 96 | - 9-2 工作流平台搭建集成spring boot1-1 97 | - 9-3 工作流平台搭建集成spring boot1-2 98 | - 9-4 工作流平台搭建集成spring boot1-3 99 | - 9-5 工作流平台搭建集成spring boot1-4 100 | - 9-6 工作流平台升级spring boot2-1 101 | - 9-7 工作流平台升级spring boot2-2 102 | - 9-8 工作流平台升级spring boot2-3 103 | - 9-9 工作流平台升级spring boot2-4 104 | - 9-10 工作流平台搭建-workflow-1 105 | - 9-11 工作流平台搭建-workflow-2 106 | - 9-12 工作流平台搭建-购物流程-1 107 | - 9-13 工作流平台搭建-购物流程-2 108 | - 9-14 工作流平台搭建-购物流程-3 109 | ### 第10章 工作流平台部署和运维 110 | - 10-1 工作流平台部署-1 111 | - 10-2 工作流平台部署-2 112 | ### 第11章 课程总结 113 | - 11-1 课程总结 114 | 115 | 课程介绍:[链接](https://blog.csdn.net/weixin_43121468/article/details/82347026) 116 | 网盘链接:https://pan.baidu.com/s/1fYddxHp94g12fMBu4I__Ww 提取码:aaaz 117 | 118 | ### 参考 119 | 120 | 1. [fhqscfss/activiti-test](https://github.com/fhqscfss/activiti-test) 121 | 2. [chandler1142/activiti-study](https://github.com/chandler1142/activiti-study) 122 | 3. [shengjie8329/activiti-helloword](https://github.com/shengjie8329/activiti-helloword) --------------------------------------------------------------------------------