一、Activiti-07-基于IDEA开发HelloWord
1. actibpm插件安装
IDEA版
- 官网下载地址:https://plugins.jetbrains.com/plugin/7429-actibpm
- 选择IDEA本地插件安装,如果是2018版的IDEA直接选择网络安装即可,2019版及以后存在插件搜索不到的问题。
Eclipse 版【推荐,但是只有固定版本才可以正常使用】
2. 新建maven骨架项目
项目流程:
添加依赖
xml<dependencies> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-engine</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.11</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>23.0</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.176</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies>
代码实现
创建流程引擎
javaprivate static ProcessEngine getProcessEngine() { // 基于内存数据库创建引擎 // 方式一: // ProcessEngineConfiguration cfg = ProcessEngineConfiguration // .createStandaloneProcessEngineConfiguration(); // ProcessEngine processEngine = cfg // .setDatabaseSchemaUpdate(ProcessEngineConfiguration // .DB_SCHEMA_UPDATE_TRUE) // .setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000") // .buildProcessEngine(); // 方式二: ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration(); ProcessEngine processEngine = cfg.buildProcessEngine(); String name = processEngine.getName(); String version = ProcessEngine.VERSION; logger.info("流程引擎名称{},版本{}", name, version); return processEngine; }
部署流程定义文件
javaprivate static ProcessDefinition getProcessDefinition(ProcessEngine processEngine) { RepositoryService repositoryService = processEngine.getRepositoryService(); DeploymentBuilder deploymentBuilder = repositoryService.createDeployment(); deploymentBuilder.addClasspathResource("diagrams/second_approve.bpmn20.xml"); Deployment deployment = deploymentBuilder.deploy(); String deploymentId = deployment.getId(); ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); logger.info("流程定义文件{}, 流程ID{}", processDefinition.getName(), processDefinition.getId()); return processDefinition; }
启动运行流程
javaprivate static ProcessInstance getProcessInstance(ProcessEngine processEngine, ProcessDefinition processDefinition) { RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId()); logger.info("启动流程 {}", processInstance.getProcessDefinitionKey()); return processInstance; }
处理流程任务
javaprivate static void processTask(ProcessEngine processEngine, ProcessInstance processInstance) throws ParseException { Scanner scanner = new Scanner(System.in); while (processInstance != null && !processInstance.isEnded()) { TaskService taskService = processEngine.getTaskService(); List<Task> list = taskService.createTaskQuery().list(); logger.info("待处理数量 {}", list.size()); for (Task task : list) { logger.info("待处理任务 {}", task.getName()); Map<String, Object> variables = getMap(processEngine, scanner, task); taskService.complete(task.getId(), variables); processInstance = processEngine.getRuntimeService() .createProcessInstanceQuery() .processInstanceId(processInstance.getId()) .singleResult(); } } scanner.close(); }
主函数调用
javaprivate static final Logger logger = LoggerFactory.getLogger(HelloWord.class); public static void main(String[] args) throws ParseException { logger.info("启动程序"); // 1. 创建流程引擎 ProcessEngine processEngine = getProcessEngine(); // 2. 部署流程定义文件 ProcessDefinition processDefinition = getProcessDefinition(processEngine); // 3. 启动运行流程 ProcessInstance processInstance = getProcessInstance(processEngine, processDefinition); // 4. 处理流程任务 processTask(processEngine, processInstance); logger.info("启动结束"); }
流程配置文件:second_approve.bpmn20.xml
xml<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test"> <process id="second_approve" name="二级审批流程" isExecutable="true"> <startEvent id="startEvent" name="开始"></startEvent> <userTask id="submit_Form" name="提交审批信息"> <extensionElements> <activiti:formProperty id="message" name="申请信息" type="string" required="true"></activiti:formProperty> <activiti:formProperty id="name" name="申请人姓名" type="string" required="true"></activiti:formProperty> <activiti:formProperty id="submitTime" name="提交时间" type="date" datePattern="yyyy-MM-dd" required="true"></activiti:formProperty> <activiti:formProperty id="submitType" name="确认申请" type="string" required="true"></activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow1" sourceRef="startEvent" targetRef="submit_Form"></sequenceFlow> <userTask id="tl_approve" name="主管审批"> <extensionElements> <activiti:formProperty id="tlResult" name="主管审批结果" type="string" required="true"></activiti:formProperty> <activiti:formProperty id="tlMessage" name="经理审批的备注" type="string" required="true"></activiti:formProperty> </extensionElements> </userTask> <exclusiveGateway id="decideTLApprove" name="主管审批校验"></exclusiveGateway> <sequenceFlow id="flow4" sourceRef="tl_approve" targetRef="decideTLApprove"></sequenceFlow> <userTask id="hr_approve" name="人事审批"> <extensionElements> <activiti:formProperty id="hrResult" name="人事审批的结果" type="string" required="true"></activiti:formProperty> <activiti:formProperty id="hrMessage" name="人事审批的备注" type="string" required="true"></activiti:formProperty> </extensionElements> </userTask> <sequenceFlow id="flow5" sourceRef="decideTLApprove" targetRef="hr_approve"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${tlResult == "y" || tlResult == "Y"}]]></conditionExpression> </sequenceFlow> <exclusiveGateway id="decideHRApprove" name="人事审批校验"></exclusiveGateway> <sequenceFlow id="flow6" sourceRef="hr_approve" targetRef="decideHRApprove"></sequenceFlow> <endEvent id="endEvent" name="结束"></endEvent> <sequenceFlow id="flow7" sourceRef="decideHRApprove" targetRef="endEvent"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrResult == "y" || hrResult == "Y"}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flow10" sourceRef="decideTLApprove" targetRef="submit_Form"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${tlResult == "n" || tlResult == "N"}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flow11" sourceRef="decideHRApprove" targetRef="submit_Form"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrResult == "n" || hrResult == "N"}]]></conditionExpression> </sequenceFlow> <endEvent id="cancelEvent" name="取消"></endEvent> <exclusiveGateway id="decideSubmit" name=" 提交OR取消"></exclusiveGateway> <sequenceFlow id="flow12" sourceRef="submit_Form" targetRef="decideSubmit"></sequenceFlow> <sequenceFlow id="flow13" sourceRef="decideSubmit" targetRef="tl_approve"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${submitType == "y" || submitType == "Y"}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="flow14" sourceRef="decideSubmit" targetRef="cancelEvent"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${submitType == "n" || submitType == "N"}]]></conditionExpression> </sequenceFlow> </process> <bpmndi:BPMNDiagram id="BPMNDiagram_second_approve"> <bpmndi:BPMNPlane bpmnElement="second_approve" id="BPMNPlane_second_approve"> <bpmndi:BPMNShape bpmnElement="startEvent" id="BPMNShape_startEvent"> <omgdc:Bounds height="35.0" width="35.0" x="30.0" y="190.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="submit_Form" id="BPMNShape_submit_Form"> <omgdc:Bounds height="55.0" width="105.0" x="110.0" y="180.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="tl_approve" id="BPMNShape_tl_approve"> <omgdc:Bounds height="55.0" width="105.0" x="345.0" y="181.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="decideTLApprove" id="BPMNShape_decideTLApprove"> <omgdc:Bounds height="40.0" width="40.0" x="495.0" y="189.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="hr_approve" id="BPMNShape_hr_approve"> <omgdc:Bounds height="55.0" width="105.0" x="580.0" y="182.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="decideHRApprove" id="BPMNShape_decideHRApprove"> <omgdc:Bounds height="40.0" width="40.0" x="730.0" y="190.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="endEvent" id="BPMNShape_endEvent"> <omgdc:Bounds height="35.0" width="35.0" x="815.0" y="193.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="cancelEvent" id="BPMNShape_cancelEvent"> <omgdc:Bounds height="35.0" width="35.0" x="380.0" y="260.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="decideSubmit" id="BPMNShape_decideSubmit"> <omgdc:Bounds height="40.0" width="40.0" x="260.0" y="188.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> <omgdi:waypoint x="65.0" y="207.0"></omgdi:waypoint> <omgdi:waypoint x="110.0" y="207.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"> <omgdi:waypoint x="450.0" y="208.0"></omgdi:waypoint> <omgdi:waypoint x="495.0" y="209.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5"> <omgdi:waypoint x="535.0" y="209.0"></omgdi:waypoint> <omgdi:waypoint x="580.0" y="209.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6"> <omgdi:waypoint x="685.0" y="209.0"></omgdi:waypoint> <omgdi:waypoint x="730.0" y="210.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7"> <omgdi:waypoint x="770.0" y="210.0"></omgdi:waypoint> <omgdi:waypoint x="815.0" y="210.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10"> <omgdi:waypoint x="515.0" y="229.0"></omgdi:waypoint> <omgdi:waypoint x="514.0" y="315.0"></omgdi:waypoint> <omgdi:waypoint x="162.0" y="315.0"></omgdi:waypoint> <omgdi:waypoint x="162.0" y="235.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11"> <omgdi:waypoint x="750.0" y="190.0"></omgdi:waypoint> <omgdi:waypoint x="749.0" y="106.0"></omgdi:waypoint> <omgdi:waypoint x="162.0" y="106.0"></omgdi:waypoint> <omgdi:waypoint x="162.0" y="180.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12"> <omgdi:waypoint x="215.0" y="207.0"></omgdi:waypoint> <omgdi:waypoint x="260.0" y="208.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13"> <omgdi:waypoint x="300.0" y="208.0"></omgdi:waypoint> <omgdi:waypoint x="345.0" y="208.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14"> <omgdi:waypoint x="280.0" y="228.0"></omgdi:waypoint> <omgdi:waypoint x="280.0" y="277.0"></omgdi:waypoint> <omgdi:waypoint x="380.0" y="277.0"></omgdi:waypoint> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>