BPMN2.0(Business Process Mo
- 是—套业务流程模型与符号建模标准
- 精准的执行语义来描述元素的操作
- 以XML为载体,以符号可视化业务
BPMN2.0元素
- 流对象(Flow Object)
-
- 活动(Activities) 【User Task 、Service Task…】
-
- 事件(Events) 【Start Event、End Event…】
-
- 网关(Gateways)【Exclusive Gateway.….】
 
核心流程任务
- Service Task 可以调用外部服务和自动执行程序,指实现JavaDelegate的业务类
- Send Task 发送任务用于处理向外部流程参与者发送消息,指的是发送邮件的任务
- Receive Task 等待外部流程参与者发送消息的任务
- User Task 需要人参与的任务
- Script Task 用于执行定义好的脚本文件
用户任务
可以通过xml里面去设置候选人和候选组,
<userTask id="someTask" name="主管审批"
activiti:candidateUsers="bushro,user1,user2"
activiti:candidateGroups="group1"/>
或者在xml里面配置监听器,通过监听器去添加候选人和候选组
<userTask id="someTask" name="User Task" >
<extensionElements>
<activiti:taskListener event="create" class="com.imooc.activiti.activitidemo.example.MyTaskListener"></activiti:taskListener>
<activiti:taskListener event="complete" class="com.imooc.activiti.activitidemo.example.MyTaskListener"></activiti:taskListener>
</extensionElements>
</userTask>
public class MyTaskListener implements TaskListener {
private static final Logger LOGGER = LoggerFactory.getLogger(MyTaskListener.class);
@Override
public void notify(DelegateTask delegateTask) {
String eventName = delegateTask.getEventName();
LOGGER.info("eventName = {}", eventName);
if (StringUtils.equals("create", eventName)) {
LOGGER.info("config by listener");
delegateTask.addCandidateUsers(Lists.newArrayList("user1", "user2"));
delegateTask.addCandidateGroup("group1");
delegateTask.setAssignee("kermit");
delegateTask.setVariable("key1", "value1");
delegateTask.setDueDate(DateTime.now().plusDays(3).toDate());
} else {
LOGGER.info("task complete");
}
}
}
如果从候选人或者候选组中指定了代理人,其他候选人就失效了
//委托代理人
taskService.claim(task.getId(), "user2");
//不推荐这样子设置代理人
//taskService.setAssignee(task.getId(), "user2");
LOGGER.info("claim task.id = {} by user2", task.getId());
//验证其他人员,当有人被指定代理后其他人就失效了
Task user1 = taskService.createTaskQuery().taskCandidateOrAssigned("user1").singleResult();
LOGGER.info("find by user1 task = {}", user1);//应该是null了
Task user2 = taskService.createTaskQuery().taskCandidateOrAssigned("user1").singleResult();
LOGGER.info("find by user2 task = {}", user2);//应该是有的了
脚本任务
- JUEL脚本(默认)
- Groovy脚本(依赖groovy-all.jar )
- JavaScript脚本
脚本任务内置变量
- execution
- xxxService等核心api
- processEngineConfiguration
<scriptTask id="scriptTask" name="script Task" scriptFormat="groovy">
<script>
def myValue = "value123"
execution.setVariable("myKey",myValue)
</script>
</scriptTask>
脚本任务设置返回值
-- juel方式
<scriptTask id="scriptTask" name="script Task" scriptFormat="juel" activiti:resultVariable="mySum">
<script >
#{key1 + key2}
</script>
</scriptTask>
-- script方式
<scriptTask id="scriptTask" name="script Task" scriptFormat="javascript" activiti:resultVariable="mySum">
<script >
key1 + key2
</script>
</scriptTask>
案例
public class ScriptTaskTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ScriptTaskTest.class);
@Rule
public ActivitiRule activitiRule = new ActivitiRule();
/**
*/
@Test
@org.activiti.engine.test.Deployment(resources = "bpmn/my-process-script.bpmn20.xml")
public void testScriptTask() {
//启动流程
RuntimeService runtimeService = activitiRule.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
HistoryService historyService = activitiRule.getHistoryService();
List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery().orderByVariableName()
.asc().listPage(0, 100);
for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
LOGGER.info("variable = {}", historicVariableInstance);
}
LOGGER.info("variables .size = {}", historicVariableInstances.size());
}
/**
* script juel取返回值
*/
@Test
@org.activiti.engine.test.Deployment(resources = "bpmn/my-process-script2.bpmn20.xml")
public void testScriptTask2() {
//启动流程
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variables = Maps.newHashMap();
variables.put("key1", 3);
variables.put("key2", 4);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
HistoryService historyService = activitiRule.getHistoryService();
List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery().orderByVariableName().asc().listPage(0, 100);
for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
LOGGER.info("variable = {}", historicVariableInstance);
}
//mySum自动赋值,juel赋为string的值
//id=5, name=key1, revision=0, type=integer, longValue=3
// id=6, name=key2, revision=0, type=integer, longValue=4
// id=10, name=mySum, revision=0, type=string, textValue=7
LOGGER.info("variables .size = {}", historicVariableInstances.size());
// variables .size = 3
}
/**
* script javascript取返回值
*/
@Test
@org.activiti.engine.test.Deployment(resources = "bpmn/my-process-script3.bpmn20.xml")
public void testScriptTask3() {
//启动流程
RuntimeService runtimeService = activitiRule.getRuntimeService();
Map<String, Object> variables = Maps.newHashMap();
variables.put("key1", 3);
variables.put("key2", 4);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
HistoryService historyService = activitiRule.getHistoryService();
List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery().orderByVariableName().desc().listPage(0, 100);
for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
LOGGER.info("variable = {}", historicVariableInstance);
}
//mySum自动赋值,javascript赋为double的值
//id=5, name=key1, revision=0, type=integer, longValue=3
// id=6, name=key2, revision=0, type=integer, longValue=4
// id=10, name=mySum, revision=0, type=double, doubleValue=7.0
LOGGER.info("variables .size = {}", historicVariableInstances.size());
// variables .size = 3
}
/**
* script 引擎测试
*/
@Test
@org.activiti.engine.test.Deployment(resources = "bpmn/my-process-script3.bpmn20.xml")
public void testScriptEngine() throws ScriptException {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("juel");
Object eval = scriptEngine.eval("${1+2}");
LOGGER.info("value = {}", eval.getClass());
}
}
服务任务
是用来执行java程序的
- 执行实现JavaDelegate或ActivityBehavior的类
- 执行一个JavaDelegate对象表达式,通常是spring配置的Bean
- 执行调用方法表达式和值表达式
执行实现JavaDelegate或ActivityBehavior的类
xml的配置
-- JavaDelegate方式
<serviceTask id="someTask" name="主管审批" activiti:class="com.imooc.activiti.activitidemo.example.MyJavaDelegate">
</serviceTask>
-- ActivityBehavior方式
<serviceTask id="someTask" name="主管审批" activiti:class="com.imooc.activiti.activitidemo.example.MyActivityBehavior"/>
- JavaDelegate直接执行
- ActivitiBehavior流程等待
JavaDelegate属性注入
<serviceTask id="someTask" name="主管审批" activiti:class="com.imooc.activiti.activitidemo.example.MyJavaDelegate">
<extensionElements>
<activiti:field name="name" stringValue="Test Java Delegate"/>
<activiti:field name="desc">
<activiti:expression>My ${desc}</activiti:expression>
</activiti:field>
</extensionElements>
</serviceTask>
JavaDelegate类
public class MyJavaDelegate implements JavaDelegate, Serializable {
private static final Logger LOGGER = LoggerFactory.getLogger(MyJavaDelegate.class);
private Expression name;
private Expression desc;
@Override
public void execute(DelegateExecution delegateExecution) {
if (name != null) {
Object value = name.getValue(delegateExecution);
LOGGER.info("name = {}", value);
}
if (desc != null) {
Object value = desc.getValue(delegateExecution);
LOGGER.info("name = {}", value);
}
LOGGER.info("run My Java Delegate {}", this);
}
}
执行一个JavaDelegate对象表达式
delegateExpression
activiti
<serviceTask id="someTask" activiti:delegateExpression="${myJavaDelegate}"/>
具体使用哪种方式需要更具业务场景来确认,如果说有一些特殊的业务场景,当执行完成后需要流程节点停顿在当前位置等待其它事件的触发就可以使用ActivitiBehavior的方式,否则一般情况下使用的是现JavaDelegate方式
|