? ? ? ?在使用springboot+activiti的serviceTask过程中,通过activiti:delegateExpression的代理方式注入bean,如${serviceTaskService}的时候,在实现@Service注解而没有指定注解值的时候将会出现以下异常
class="java" name="code">org.activiti.engine.ActivitiException: Unknown property used in expression: ${serviceTaskService} at org.activiti.engine.impl.bpmn.behavior.ServiceTaskDelegateExpressionActivityBehavior.execute(ServiceTaskDelegateExpressionActivityBehavior.java:119) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.agenda.ContinueProcessOperation.executeActivityBehavior(ContinueProcessOperation.java:180) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.agenda.ContinueProcessOperation.executeSynchronous(ContinueProcessOperation.java:131) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.agenda.ContinueProcessOperation.continueThroughFlowNode(ContinueProcessOperation.java:89) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.agenda.ContinueProcessOperation.run(ContinueProcessOperation.java:55) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:73) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:57) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:42) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:48) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:63) ~[activiti-engine-6.0.0.jar:6.0.0] at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47) [activiti-spring-6.0.0.jar:6.0.0] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) [spring-tx-4.3.18.RELEASE.jar:4.3.18.RELEASE] at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45) [activiti-spring-6.0.0.jar:6.0.0] at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:29) [activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:44) [activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:39) [activiti-engine-6.0.0.jar:6.0.0] at org.activiti.engine.impl.RuntimeServiceImpl.startProcessInstanceByKey(RuntimeServiceImpl.java:82) [activiti-engine-6.0.0.jar:6.0.0] at com.activiti.service.impl.OverTimerServiceImpl.startWorkFlow(OverTimerServiceImpl.java:29) [classes/:na]
? ? ? ? ? 刚开始的时候一直没有找到问题的原因,通过慢慢摸索原来只需要把注解@Servcie修改为@Service(value="serviceTaskService")即给该注解添加值就可以了,这是一个相当郁闷的事情,因为spring通常会自动的按照接口类来默认给注解取值,但是在activiti的serviceTask通过代理的时候就出问题了,这可能跟activiti的代码实现由关,没有实现初始缓存的原因,所以调用的时候就出问题了。下面贴下代码
?
serviceTest.bpmn20.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:xsd="http://www.w3.org/2001/XMLSchema" 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://activiti.org/test"> <process id="serviceTest" name="serviceTest" isExecutable="true"> <endEvent id="end" name="end"/> <sequenceFlow sourceRef="start" targetRef="task1" id="start-task1"/> <sequenceFlow sourceRef="task1" targetRef="task2" id="task1-task2"/> <sequenceFlow sourceRef="task2" targetRef="end" id="task2-end"/> <serviceTask id="task1" name="任务1" activiti:delegateExpression="${serviceTaskService}"/> <serviceTask id="task2" name="任务2" activiti:delegateExpression="${serviceTaskService}"/> <startEvent id="start" name="start"/> </process> <bpmndi:BPMNDiagram> <bpmndi:BPMNPlane> <bpmndi:BPMNShape bpmnElement="start"> <omgdc:Bounds height="48.0" width="51.0" x="-12.0" y="-4.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="task1"> <omgdc:Bounds height="64.0" width="84.0" x="159.0" y="-10.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="end"> <omgdc:Bounds height="51.0" width="56.0" x="450.0" y="3.0"/> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> <bpmndi:BPMNDiagram> <bpmndi:BPMNPlane> <bpmndi:BPMNShape bpmnElement="task2"> <omgdc:Bounds height="71.0" width="83.0" x="427.0" y="55.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="end"> <omgdc:Bounds height="48.0" width="48.0" x="660.0" y="68.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="task1"> <omgdc:Bounds height="48.0" width="120.0" x="210.0" y="65.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="start"> <omgdc:Bounds height="48.0" width="48.0" x="39.0" y="61.0"/> </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>
?
?
ServiceTaskService接口:
import org.activiti.engine.delegate.JavaDelegate; /** * @version 1.0 * @date 2018/7/12 * @description */ public interface ServiceTaskService extends JavaDelegate { }
?
ServiceTaskServiceImpl实现类:
import com.activiti.service.ServiceTaskService; import org.activiti.engine.delegate.DelegateExecution; import org.springframework.stereotype.Service; /** * @version 1.0 * @date 2018/7/12 * @description */ @Service(value = "serviceTaskService") public class ServiceTaskServiceImpl implements ServiceTaskService { @Override public void execute(DelegateExecution delegateExecution) { System.out.println("当前节点:" + delegateExecution.getCurrentFlowElement().getName()); } }
?controller启动类:
package com.activiti.service.impl; import org.activiti.engine.RuntimeService; import org.activiti.engine.runtime.ProcessInstance; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.GetMapping; import javax.annotation.Resource; import java.util.Optional; /** * @version 1.0 * @date 2018/7/10 * @description */ @RestController public class ServiceTaskController { @Resource private RuntimeService runtimeService; @Transactional(rollbackFor = Exception.class) @GetMapping(value = "/startWorkflow") public boolean startWorkflow(@RequestParam(value = "workFlowName")String workFlowName) { // 通过流程定义的key启动,选取最高的version启动 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(workFlowName); if (Optional.ofNullable(processInstance).isPresent() && processInstance.getProcessInstanceId().length() > 0) { return true; } return false; } }
?maven配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId> <artifactId>test_springboot_activiti</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.14.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter-basic</artifactId> <version>6.0.0</version> </dependency> <!--<dependency> <groupId>org.activiti</groupId> <artifactId>activiti5-engine</artifactId> <version>6.0.0</version> </dependency>--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--HikariCP数据连接池 --> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
?更多例子可以参考https://github.com/422518490/test_springboot_activiti