activiti实践
本实例是完整源码,能够满足大多业务需求了.
流程图如下:
<definitions id="definitions"
targetNamespace="test-namespace"
xmlns:activiti="http://activiti.org/bpmn"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
<process id="test1" name="test-name">
<startEvent id="theStart" activiti:initiator="huser">
<extensionElements>
<activiti:formProperty id="boundTime" name="time" required="true" type="string"/>
</extensionElements>
</startEvent>
<userTask id="user-task-1">
<extensionElements>
<activiti:taskListener event="create" class="com.example.demo.MyTaskListenter"></activiti:taskListener>
<activiti:executionListener event="start" class="com.example.demo.MyExecutionLister"/>
</extensionElements>
</userTask>
<!-- 超时时间 -->
<boundaryEvent attachedToRef="user-task-1" id="bound-1" name="bound-1" cancelActivity="true">
<timerEventDefinition>
<timeDuration>${boundTime}</timeDuration>
</timerEventDefinition>
</boundaryEvent>
<!-- 委托给java服务执行 -->
<serviceTask id="service-1" activiti:delegateExpression="${service1}" >
<extensionElements>
<activiti:field name="name" stringValue="Hello Service 1"/>
</extensionElements>
</serviceTask>
<!-- 多实例子流程 -->
<subProcess id="subp-1" name="subp-1">
<!-- 多实例配置 -->
<multiInstanceLoopCharacteristics isSequential="false">
<loopDataInputRef>subMulti</loopDataInputRef>
<inputDataItem name="myAssignee"></inputDataItem>
</multiInstanceLoopCharacteristics>
<startEvent id="sub-start-1" activiti:initiator="startUser"></startEvent>
<intermediateCatchEvent id="time-2">
<timerEventDefinition>
<timeDuration>PT5S</timeDuration>
</timerEventDefinition>
</intermediateCatchEvent>
<endEvent id="sub-end-1">
<extensionElements>
<activiti:executionListener event="start" class="com.example.demo.MyExecutionLister"/>
</extensionElements>
</endEvent>
<sequenceFlow sourceRef="sub-start-1" targetRef="time-2" id="s-1"/>
<sequenceFlow sourceRef="time-2" targetRef="sub-end-1" id="s-2"/>
<!-- 多实例配置,可用于子流程,usertask等,遍历subMulti,赋值给myAssignee,循环调用子流程 -->
</subProcess>
<endEvent id="theEnd" />
<!-- 连线配置 -->
<sequenceFlow sourceRef="theStart" targetRef="user-task-1" id="f-1"></sequenceFlow>
<sequenceFlow sourceRef="user-task-1" targetRef="service-1" id="f-2"/>
<sequenceFlow sourceRef="bound-1" targetRef="service-1" id="f-3"/>
<sequenceFlow sourceRef="service-1" targetRef="subp-1" id="f-4"/>
<sequenceFlow sourceRef="subp-1" targetRef="theEnd"/>
</process>
</definitions>
配置:
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="true" />
<property name="asyncExecutorEnabled" value="true"/>
<property name="asyncExecutorActivate" value="true"/>
<property name="deploymentResources">
<list>
<value>classpath:test1.bpmn20.xml</value>
<value>classpath:test2.bpmn20.xml</value>
<value>classpath:test3.bpmn20.xml</value>
</list>
</property>
<property name="eventDispatcher">
<bean class="com.example.demo.MyActivitiEventDispatcherImpl"></bean>
</property>
<property name="eventListeners">
<list>
<bean class="com.example.demo.MyEventListener"/>
</list>
</property>
<property name="typedEventListeners">
<map>
<entry key="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" >
<list>
<bean class="com.example.demo.MyEventListener" />
</list>
</entry>
</map>
</property>
<property name="historyLevel" value="FULL"/>
<property name="enableDatabaseEventLogging" value="true"/>
</bean>
MyEventListener:事件监听器
@Slf4j
public class MyEventListener implements ActivitiEventListener {
@Override
public void onEvent(ActivitiEvent event) {
switch (event.getType()) {
case JOB_EXECUTION_SUCCESS:
log.info("A job well done!");
break;
case JOB_EXECUTION_FAILURE:
log.info("A job has failed...");
break;
default:
log.info("Event received: " + event.getType());
}
}
@Override
public boolean isFailOnException() {
return false;
}
}
执行监听,监听活动的执行
public class MyExecutionLister implements ExecutionListener {
@Override
public void notify(DelegateExecution execution) throws Exception {
String currentActivityId = execution.getCurrentActivityId();
System.out.println("execution:"+currentActivityId);
Object myAssignee = execution.getVariable("myAssignee");
System.out.println("end-assigness:"+myAssignee);
}
}
task监听器,能够监听task的创建等等事件
public class MyTaskListenter implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
System.out.println("任务创建:"+delegateTask.getProcessInstanceId());
}
}
java委托服务处理类
@Component
@Scope("prototype")
public class Service1 implements JavaDelegate {
private Expression name;
@Override
public void execute(DelegateExecution execution) throws Exception {
Object value = name.getValue(execution);
System.out.println("服务获取到值:"+value);
Map<String, Object> variables = execution.getVariables();
for (String v : variables.keySet()) {
System.out.println(v +":"+variables.get(v));
}
execution.setVariable("recipient","aa");
}
}
启动流程编码:
RepositoryService repositoryService = context.getBean(RepositoryService.class);
RuntimeService runtimeService = context.getBean(RuntimeService.class);
IdentityService identityService = context.getBean(IdentityService.class);
TaskService taskService = context.getBean(TaskService.class);
SpringProcessEngineConfiguration processEngineConfiguration = context.getBean(SpringProcessEngineConfiguration.class);
ProcessDiagramGenerator processDiagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
HistoryService historyService = context.getBean(HistoryService.class);
HashMap<String, Object> params = new HashMap<>();
params.put("huser", "huser-1");
params.put("boundTime", "PT5S");
params.put("subMulti", Arrays.asList("subMulti_1","subMulti_2","subMulti_3"));
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("test1", params);