部署的流程可以使用Activiti API来启动、运行、查看历史记录以及以其他方式管理流程实例,本快速入门使用Java代码运行流程实例。
将Activiti的日志记录级别从DEBUG设置为WARN,如下面的第1行所示。
log4j.rootLogger=WARN, ACT log4j.appender.ACT=org.apache.log4j.ConsoleAppender log4j.appender.ACT.layout=org.apache.log4j.PatternLayout log4j.appender.ACT.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n
添加到 OnboardingRequest.java
,如下图所示:
package com.example; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; import org.activiti.engine.FormService; import org.activiti.engine.HistoryService; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.form.FormData; import org.activiti.engine.form.FormProperty; import org.activiti.engine.history.HistoricActivityInstance; import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration; import org.activiti.engine.impl.form.DateFormType; import org.activiti.engine.impl.form.LongFormType; import org.activiti.engine.impl.form.StringFormType; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; public class OnboardingRequest { public static void main(String[] args) throws ParseException { ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration() .setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000") .setJdbcUsername("sa") .setJdbcPassword("") .setJdbcDriver("org.h2.Driver") .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); ProcessEngine processEngine = cfg.buildProcessEngine(); String pName = processEngine.getName(); String ver = ProcessEngine.VERSION; System.out.println("ProcessEngine [" + pName + "] Version: [" + ver + "]"); RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deployment = repositoryService.createDeployment() .addClasspathResource("onboarding.bpmn20.xml").deploy(); ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() .deploymentId(deployment.getId()).singleResult(); System.out.println( "Found process definition [" + processDefinition.getName() + "] with id [" + processDefinition.getId() + "]"); RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance = runtimeService .startProcessInstanceByKey("onboarding"); System.out.println("Onboarding process started with process instance id [" + processInstance.getProcessInstanceId() + "] key [" + processInstance.getProcessDefinitionKey() + "]"); TaskService taskService = processEngine.getTaskService(); FormService formService = processEngine.getFormService(); HistoryService historyService = processEngine.getHistoryService(); Scanner scanner = new Scanner(System.in); while (processInstance != null && !processInstance.isEnded()) { List<Task> tasks = taskService.createTaskQuery() .taskCandidateGroup("managers").list(); System.out.println("Active outstanding tasks: [" + tasks.size() + "]"); for (int i = 0; i < tasks.size(); i++) { Task task = tasks.get(i); System.out.println("Processing Task [" + task.getName() + "]"); Map<String, Object> variables = new HashMap<String, Object>(); FormData formData = formService.getTaskFormData(task.getId()); for (FormProperty formProperty : formData.getFormProperties()) { if (StringFormType.class.isInstance(formProperty.getType())) { System.out.println(formProperty.getName() + "?"); String value = scanner.nextLine(); variables.put(formProperty.getId(), value); } else if (LongFormType.class.isInstance(formProperty.getType())) { System.out.println(formProperty.getName() + "? (Must be a whole number)"); Long value = Long.valueOf(scanner.nextLine()); variables.put(formProperty.getId(), value); } else if (DateFormType.class.isInstance(formProperty.getType())) { System.out.println(formProperty.getName() + "? (Must be a date m/d/yy)"); DateFormat dateFormat = new SimpleDateFormat("m/d/yy"); Date value = dateFormat.parse(scanner.nextLine()); variables.put(formProperty.getId(), value); } else { System.out.println("<form type not supported>"); } } taskService.complete(task.getId(), variables); HistoricActivityInstance endActivity = null; List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstance.getId()).finished() .orderByHistoricActivityInstanceEndTime().asc() .list(); for (HistoricActivityInstance activity : activities) { if (activity.getActivityType() == "startEvent") { System.out.println("BEGIN " + processDefinition.getName() + " [" + processInstance.getProcessDefinitionKey() + "] " + activity.getStartTime()); } if (activity.getActivityType() == "endEvent") { // Handle edge case where end step happens so fast that the end step // and previous step(s) are sorted the same. So, cache the end step //and display it last to represent the logical sequence. endActivity = activity; } else { System.out.println("-- " + activity.getActivityName() + " [" + activity.getActivityId() + "] " + activity.getDurationInMillis() + " ms"); } } if (endActivity != null) { System.out.println("-- " + endActivity.getActivityName() + " [" + endActivity.getActivityId() + "] " + endActivity.getDurationInMillis() + " ms"); System.out.println("COMPLETE " + processDefinition.getName() + " [" + processInstance.getProcessDefinitionKey() + "] " + endActivity.getEndTime()); } } // Re-query the process instance, making sure the latest state is available processInstance = runtimeService.createProcessInstanceQuery() .processInstanceId(processInstance.getId()).singleResult(); } scanner.close(); } }
行数 | 说明 |
---|---|
12-13, 17-21, 28-39 | Activiti API中的主要服务导入用于流程管理。 |
54-59 | 启动Onboarding流程的实例。 |
61-62, 67, 71-93 | 从符合“manager”角色的任务中收集命令行输入并完成任务。 |
23-25, 76,80, 84 | 基于流程模型中定义的表单属性类型,提示用户输入特定于类型的输入。 |
63, 95-125 | 显示流程历史记录。 |
23-25 | 检索已部署的模型,证明它位于Activiti存储库中 |
通过运行“mvn package”打包代码。
像以前一样运行Java程序,注意下面提到的示例输出。
ProcessEngine [default] Version: [5.22.0.0] Found process definition [Onboarding] with id [onboarding:1:4] Onboarding process started with process instance id [5] key [onboarding] Active outstanding tasks: [1] Processing Task [Enter Data] Full Name? John Doe Years of Experience? (Must be a whole number) 2 BEGIN Onboarding [onboarding] Sun Nov 27 21:36:21 EST 2016 -- Start [startOnboarding] 4 ms -- Enter Data [enterOnboardingData] 16855 ms -- Years of Experience [decision] 3 ms -- Generic and Automated Data Entry [automatedIntro] 322 ms -- End [endOnboarding] 0 ms COMPLETE Onboarding [onboarding] Sun Nov 27 21:36:38 EST 2016
观察2年经验在“Years of Experience”决定之后看到脚本任务“Generic and Automated Data Entry”之后的流程路径,然后流程结束。
ProcessEngine [default] Version: [5.22.0.0] Found process definition [Onboarding] with id [onboarding:1:4] Onboarding process started with process instance id [5] key [onboarding] Active outstanding tasks: [1] Processing Task [Enter Data] Full Name? John Doe Years of Experience? (Must be a whole number) 5 BEGIN Onboarding [onboarding] Sun Nov 27 21:39:26 EST 2016 -- Start [startOnboarding] 5 ms -- Enter Data [enterOnboardingData] 7810 ms -- Years of Experience [decision] 2 ms Active outstanding tasks: [1] Processing Task [Personalized Introduction and Data Entry] Personal Welcome Time? (Must be a date m/d/yy) 12/9/16 BEGIN Onboarding [onboarding] Sun Nov 27 21:39:26 EST 2016 -- Start [startOnboarding] 5 ms -- Enter Data [enterOnboardingData] 7810 ms -- Years of Experience [decision] 2 ms -- Personalized Introduction and Data Entry [personalizedIntro] 20231 ms -- End [endOnboarding] 0 ms COMPLETE Onboarding [onboarding] Sun Nov 27 21:39:54 EST 2016
观察5年经验在“Years of Experience”Personalized Introduction and Data Entry“个性化介绍和数据输入”之后的流程路径,然后流程结束。
虽然简单,但这个嵌入式示例显示了你的应用程序如何将流程逻辑外部化为基于标准的建模和代码友好的开发模型。