1. 程式人生 > >工作流Activiti初體驗【一】

工作流Activiti初體驗【一】

【寫在前面】如果看完這篇部落格,對你有幫助的話,歡迎加入全棧技術交流群,群內不定時釋出熱門學習資料,也歡迎進行技術交流,對我的部落格有疑問也可以在群裡@我。《全棧技術交流群歡迎你

最近看同事寫的工作流bpmn,子流程沒有用到多例項,但是神奇的實現了多例項的功能,後來我接手這個專案以後,改了一下bpmn。在設定多例項之前,那神奇的效果消失了…


在這裡記錄一下我的Activiti歷程:(以下示例不涉及真實業務,所有邏輯均建立在學習的基礎上)

bpmn圖
bpmn

發起任務我設定了一個許可權組user1,只要是這個許可權的使用者都可以發起任務
許可權組
分發任務我設定了一個使用者組,使用者組中每個使用者都可以處理這步流程,只要有一個人處理這步任務,分發的流程就算結束了
分發任務


分發任務這一環節還有個判斷,允許任務下發和不允許任務下發
判斷
任務分發完成則來到子流程,每個被分到任務的人需要執行任務,所以需要派生出多個例項。子流程裡面使用者集users包含著每一個user
子流程
子流程裡面開始的事件需要接收使用者引數生產每個例項
執行任務
後面的步驟跟前面差不多,就不細說了


程式碼部分

配置檔案xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 配置流程引擎配置物件 -->
    <bean id="processEngineConfiguration"
          class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/activiti?characterEncoding=utf8&amp;useSSL=false&amp;nullCatalogMeansCurrent=true" />
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="MySQLadmin1!" />
        <!-- 建表策略:若沒有工作流表則建立,若存在工作流表則更新 -->
        <property name="databaseSchemaUpdate" value="true" />
    </bean>

    <!-- 配置一個流程引擎工廠bean,用於建立流程引擎物件 -->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <!-- 通過set方法注入流程引擎配置物件 -->
        <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>
</beans>

ActivitiConfig.java

package com.avanty.activiti;

import org.activiti.engine.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ActivitiConfig {

	/**
	 * 配合xml配置檔案使用
	 */
	@Bean
	public ProcessEngine processEngine() {
		String resource = "activiti/activitiConfig.xml";
		String beanName = "processEngineConfiguration";
		ProcessEngineConfiguration conf = ProcessEngineConfiguration
				.createProcessEngineConfigurationFromResource(resource, beanName);
		return conf.buildProcessEngine();
	}

	/**
	 * @Bean可以用xml配置,也可以程式碼配置
	 * @Bean public ProcessEngine processEngine() { //建立Activiti配置物件例項
	 *       ProcessEngineConfiguration configuration =
	 *       ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
	 *       configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
	 *       configuration.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/activiti?characterEncoding=utf8&useSSL=false&nullCatalogMeansCurrent=true");
	 *       configuration.setJdbcUsername("root");
	 *       configuration.setJdbcPassword("MySQLadmin1!"); //設定建表策略
	 *       configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
	 *       //得到引擎例項 return configuration.buildProcessEngine(); }
	 */

	@Bean
	public RepositoryService repositoryService(ProcessEngine processEngine) {
		return processEngine.getRepositoryService();
	}

	@Bean
	public RuntimeService runtimeService(ProcessEngine processEngine) {
		return processEngine.getRuntimeService();
	}

	@Bean
	public TaskService taskService(ProcessEngine processEngine) {
		return processEngine.getTaskService();
	}

	@Bean
	public HistoryService historyService(ProcessEngine processEngine) {
		return processEngine.getHistoryService();
	}

	@Bean
	public ManagementService managementService(ProcessEngine processEngine) {
		return processEngine.getManagementService();
	}

	@Bean
	public IdentityService identityService(ProcessEngine processEngine) {
		return processEngine.getIdentityService();
	}

}

用來測試的DeployActiviti.java

package com.avanty.activiti;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class DeployActiviti implements ApplicationRunner {

	/**
	 * 流程部署相關表 `ACT_RE_DEPLOYMENT` `ACT_RE_MODEL` `ACT_GE_BYTEARRAY`
	 * `ACT_GE_PROPERTY` `ACT_RE_PROCDEF`
	 */

	/**
	 * 流程執行相關表 `ACT_RU_EXECUTION` `ACT_RU_IDENTITYLINK` `ACT_RU_JOB` `ACT_RU_TASK`
	 * `ACT_RU_VARIABLE`
	 */

	/**
	 * 流程歷史相關表 `ACT_HI_IDENTITYLINK` `ACT_HI_VARINST` `ACT_HI_ACTINST`
	 * `ACT_HI_TASKINST`
	 */

	/**
	 * TaskQuery taskQuery = taskService.createTaskQuery();
	 * taskQuery.taskCandidateGroupIn(roleList);
	 * taskQuery.taskCandidateOrAssigned(usrnames);
	 * taskQuery.includeProcessVariables(); taskList = taskQuery.list();
	 */

	@Autowired
	ProcessEngine processEngine;

	@Autowired
	RuntimeService runtimeService;

	@Autowired
	TaskService taskService;

	@Override
	public void run(ApplicationArguments args) {
		finish();
	}

	private void deployProcess() {
		RepositoryService service = processEngine.getRepositoryService();
		InputStream bpmn = this.getClass().getResourceAsStream("/activiti/Process.bpmn");
		Deployment deployment = service.createDeployment().name("任務流程").addInputStream("Process.bpmn", bpmn).deploy();
		System.out.println(deployment.getName());
		System.out.println(deployment.getId());
	}

	/**
	 * 發起任務
	 */
	private void step1() {
		String processInstanceByKey = "Process";
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processInstanceByKey);
		System.out.println(processInstance.getId());
	}

	/**
	 * 檢視發起任務
	 */
	private void findStep1() {
		TaskQuery taskQuery = taskService.createTaskQuery();
		List<String> roleCodeList = new ArrayList<>();
		roleCodeList.add("user1");
		taskQuery.taskCandidateGroupIn(roleCodeList);
		taskQuery.includeProcessVariables();
		List<Task> tasks = taskQuery.list();
		for (Task task : tasks) {
			System.out.println(task.getId());
			System.out.println(task.getProcessInstanceId());
			System.out.println(task.getName());
			System.out.println(task.getAssignee());
		}
	}

	/**
	 * 分發任務
	 */
	private void step2() {
		TaskQuery taskQuery = taskService.createTaskQuery();
		List<String> roleCodeList = new ArrayList<>();
		roleCodeList.add("user1");
		taskQuery.taskCandidateGroupIn(roleCodeList);
		taskQuery.includeProcessVariables();
		Task task = taskQuery.singleResult();

		Map<String, Object> variables = new HashMap<>();
		List<String> users = new ArrayList<>();
		users.add("Michael");
		users.add("Zhan");
		variables.put("users", users);
		taskService.complete(task.getId(), variables);
		System.out.println("finish");
	}

	/**
	 * 檢視分發任務
	 */
	private void findStep2() {
		String assignee = "Zhan";
		// String assignee = "Michael";
		List<Task> tasks1 = taskService.createTaskQuery().taskCandidateUser(assignee).list();
		for (Task task1 : tasks1) {
			System.out.println(task1.getId());
			System.out.println(task1.getName());
		}
	}

	/**
	 * 子流程-執行任務
	 */
	private void step3() {
		TaskQuery taskQuery = taskService.createTaskQuery();
		taskQuery.taskCandidateOrAssigned("Michael");
		taskQuery.includeProcessVariables();
		Task task = taskQuery.singleResult();
		System.out.println(task.getId());
		Map<String, Object> variables = new HashMap<>();
		List<String> users = new ArrayList<>();
		users.add("admin");
		users.add("root");
		variables.put("users", users);
		variables.put("isPass", 1);
		taskService.complete(task.getId(), variables);
		System.out.println("finish");
	}

	/**
	 * 子流程-檢視執行任務
	 */
	private void findStep3() {
		 String assignee = "admin";
//		String assignee = "root";
		List<Task> tasks = taskService.createTaskQuery().taskCandidateOrAssigned(assignee).list();
		for (Task task : tasks) {
			System.out.println(task.getId());
			System.out.println(task.getProcessInstanceId());
			System.out.println(task.getName());
		}
	}

	/**
	 * 子流程-驗收任務
	 */
	private void step4() {
		String assignee = "admin";
		Task task = taskService.createTaskQuery().taskCandidateOrAssigned(assignee).singleResult();
		System.out.println(task.getId());
		Map<String, Object> variables = new HashMap<>();
		List<String> users = new ArrayList<>();
		if (assignee.equals("root")) {
			users.add("administrator");
			users.add("su");
		}else if(assignee.equals("admin")) {
			users.add("alex");
			users.add("sudo");
		}
		variables.put("users", users);
		taskService.complete(task.getId(), variables);
		System.out.println("finish");
	}

	/**
	 * 子流程-檢視驗收任務
	 */
	private void findStep4() {
//		 String assignee = "administrator";
//		String assignee = "su";
//		String assignee = "alex";
		String assignee = "sudo";
		List<Task> tasks = taskService.createTaskQuery().taskCandidateOrAssigned(assignee).list();
		for (Task task : tasks) {
			System.out.println(task.getId());
			System.out.println(task.getProcessInstanceId());
			System.out.println(task.getName());
		}
	}

	/**
	 * 子流程-完成
	 */
	private void finish() {
		String assignee = "alex";
		Task task = taskService.createTaskQuery().taskCandidateOrAssigned(assignee).singleResult();
		Map<String, Object> variables = new HashMap<>();
		variables.put("isPass", 1);
		taskService.complete(task.getId(), variables);
		System.out.println("finish");
	}

}


最後,附上專案地址 Activiti-Test
專案是用Eclipse寫的,不用IDEA的原因是Eclipse的Activiti外掛比IDEA的好,有自動對齊功能,強迫症的福音吶!
好了,如果有什麼疑問,可以來群裡找我,如果沒什麼疑問,也可以來群裡找我,掰掰~