系列文章目录
第一章 springboot+Activiti7整合实践 (一)
第二章 springboot+Activiti7整合实践 (二) 模型定义
第三章 springboot+Activiti7整合实践 (三) 流程定义
第四章 springboot+Activiti7整合实践 (四) 分配规则
第五章 springboot+Activiti7整合实践 (五) 发布流程
第六章 springboot+Activiti7整合实践 (六) 启动流程(1)
目录
二、继承DefaultActivityBehaviorFactory类
前言
前面的章节,通过选择用户、角色、部门的方式,我们外部定义了任务的代办人规则,这些规则是存储在我们自定义的数据库表中,那么如何使在工作流程中生效,这里我使用的方式是自定义用户任务行为,重写handleAssignments方法,设置任务的候选用户,接下来分享实现步骤。
一、继承UserTaskActivityBehavior类
public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
@Setter
private WorkTaskAssignRuleService workTaskAssignRuleService;
public BpmUserTaskActivityBehavior(UserTask userTask) {
super(userTask);
}
@Override
protected void handleAssignments(TaskEntityManager taskEntityManager, String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution) {
// 第一步,获得任务的候选用户
Set<String> userIdSet = calculateTaskCandidateUsers(execution);
candidateUsers = userIdSet.stream().collect(Collectors.toList());
super.handleAssignments(taskEntityManager,assignee,owner,candidateUsers,candidateGroups,task,expressionManager,execution);
private Set<String> calculateTaskCandidateUsers(DelegateExecution execution) {
// 情况一,如果是多实例的任务,例如说会签、或签等情况,则从 Variable 中获取。
if (super.multiInstanceActivityBehavior != null) {
String id = execution.getVariable(super.multiInstanceActivityBehavior.getCollectionElementVariable(), String.class);
Set<String> set = new HashSet<>();
set.add(id);
return set;
}
Set<String> candidateUserIds = workTaskAssignRuleService.calculateTaskCandidateUsers(execution);
return candidateUserIds;
}
}
成员变量workTaskAssignRuleServe是我们规则定义的服务类,需要依赖此对象,查询出模型定义阶段定义的分配规则,得到设置的用户id,设置到候选人用户组属性中。
UserTaskActivityBehavior介绍:在Activiti中,每个活动节点都有对应的行为类,UserTaskActivityBehavior即为用户任务的行为类,每当流转到用户任务时,就会触发行为,有两个比较常用的方法,execute和handleAssignments,execute方法时用户任务执行就会触发,里面对调用到handleAssignments方法来分配代办人、代办人组等,感兴趣的可以看看源码。
public void execute(DelegateExecution execution) {
CommandContext commandContext = Context.getCommandContext();
TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
TaskEntity task = taskEntityManager.create();
task.setExecution((ExecutionEntity) execution);
task.setTaskDefinitionKey(userTask.getId());
String activeTaskName = null;
String activeTaskDescription = null;
String activeTaskDueDate = null;
String activeTaskPriority = null;
String activeTaskCategory = null;
String activeTaskFormKey = null;
String activeTaskSkipExpression = null;
String activeTaskAssignee = null;
String activeTaskOwner = null;
List<String> activeTaskCandidateUsers = null;
List<String> activeTaskCandidateGroups = null;
ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration();
ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
if (Context.getProcessEngineConfiguration().isEnableProcessDefinitionInfoCache()) {
ObjectNode taskElementProperties = Context.getBpmnOverrideElementProperties(userTask.getId(), execution.getProcessDefinitionId());
activeTaskName = getActiveValue(userTask.getName(), DynamicBpmnConstants.USER_TASK_NAME, taskElementProperties);
activeTaskDescription = getActiveValue(userTask.getDocumentation(), DynamicBpmnConstants.USER_TASK_DESCRIPTION, taskElementProperties);
activeTaskDueDate = getActiveValue(userTask.getDueDate(), DynamicBpmnConstants.USER_TASK_DUEDATE, taskElementProperties);
activeTaskPriority = getActiveValue(userTask.getPriority(), DynamicBpmnConstants.USER_TASK_PRIORITY, taskElementProperties);
activeTaskCategory = getActiveValue(userTask.getCategory(), DynamicBpmnConstants.USER_TASK_CATEGORY, taskElementProperties);
activeTaskFormKey = getActiveValue(userTask.getFormKey(), DynamicBpmnConstants.USER_TASK_FORM_KEY, taskElementProperties);
activeTaskSkipExpression = getActiveValue(userTask.getSkipExpression(), DynamicBpmnConstants.TASK_SKIP_EXPRESSION, taskElementProperties);
activeTaskAssignee = getActiveValue(userTask.getAssignee(), DynamicBpmnConstants.USER_TASK_ASSIGNEE, taskElementProperties);
activeTaskOwner = getActiveValue(userTask.getOwner(), DynamicBpmnConstants.USER_TASK_OWNER, taskElementProperties);
activeTaskCandidateUsers = getActiveValueList(userTask.getCandidateUsers(), DynamicBpmnConstants.USER_TASK_CANDIDATE_USERS, taskElementProperties);
activeTaskCandidateGroups = getActiveValueList(userTask.getCandidateGroups(), DynamicBpmnConstants.USER_TASK_CANDIDATE_GROUPS, taskElementProperties);
} else {
activeTaskName = userTask.getName();
activeTaskDescription = userTask.getDocumentation();
activeTaskDueDate = userTask.getDueDate();
activeTaskPriority = userTask.getPriority();
activeTaskCategory = userTask.getCategory();
activeTaskFormKey = userTask.getFormKey();
activeTaskSkipExpression = userTask.getSkipExpression();
activeTaskAssignee = userTask.getAssignee();
activeTaskOwner = userTask.getOwner();
activeTaskCandidateUsers = userTask.getCandidateUsers();
activeTaskCandidateGroups = userTask.getCandidateGroups();
}
if (StringUtils.isNotEmpty(activeTaskName)) {
String name = null;
try {
name = (String) expressionManager.createExpression(activeTaskName).getValue(execution);
} catch (ActivitiException e) {
name = activeTaskName;
LOGGER.warn("property not found in task name expression " + e.getMessage());
}
task.setName(name);
}
if (StringUtils.isNotEmpty(activeTaskDescription)) {
String description = null;
try {
description = (String) expressionManager.createExpression(activeTaskDescription).getValue(execution);
} catch (ActivitiException e) {
description = activeTaskDescription;
LOGGER.warn("property not found in task description expression " + e.getMessage());
}
task.setDescription(description);
}
if (StringUtils.isNotEmpty(activeTaskDueDate)) {
Object dueDate = expressionManager.createExpression(activeTaskDueDate).getValue(execution);
if (dueDate != null) {
if (dueDate instanceof Date) {
task.setDueDate((Date) dueDate);
} else if (dueDate instanceof String) {
String businessCalendarName = null;
if (StringUtils.isNotEmpty(userTask.getBusinessCalendarName())) {
businessCalendarName = expressionManager.createExpression(userTask.getBusinessCalendarName()).getValue(execution).toString();
} else {
businessCalendarName = DueDateBusinessCalendar.NAME;
}
BusinessCalendar businessCalendar = Context.getProcessEngineConfiguration().getBusinessCalendarManager()
.getBusinessCalendar(businessCalendarName);
task.setDueDate(businessCalendar.resolveDuedate((String) dueDate));
} else {
throw new ActivitiIllegalArgumentException("Due date expression does not resolve to a Date or Date string: " + activeTaskDueDate);
}
}
}
if (StringUtils.isNotEmpty(activeTaskPriority)) {
final Object priority = expressionManager.createExpression(activeTaskPriority).getValue(execution);
if (priority != null) {
if (priority instanceof String) {
try {
task.setPriority(Integer.valueOf((String) priority));
} catch (NumberFormatException e) {
throw new ActivitiIllegalArgumentException("Priority does not resolve to a number: " + priority, e);
}
} else if (priority instanceof Number) {
task.setPriority(((Number) priority).intValue());
} else {
throw new ActivitiIllegalArgumentException("Priority expression does not resolve to a number: " + activeTaskPriority);
}
}
}
if (StringUtils.isNotEmpty(activeTaskCategory)) {
final Object category = expressionManager.createExpression(activeTaskCategory).getValue(execution);
if (category != null) {
if (category instanceof String) {
task.setCategory((String) category);
} else {
throw new ActivitiIllegalArgumentException("Category expression does not resolve to a string: " + activeTaskCategory);
}
}
}
if (StringUtils.isNotEmpty(activeTaskFormKey)) {
final Object formKey = expressionManager.createExpression(activeTaskFormKey).getValue(execution);
if (formKey != null) {
if (formKey instanceof String) {
task.setFormKey((String) formKey);
} else {
throw new ActivitiIllegalArgumentException("FormKey expression does not resolve to a string: " + activeTaskFormKey);
}
}
}
taskEntityManager.insert(task, (ExecutionEntity) execution);
task.setVariablesLocal(calculateInputVariables(execution));
boolean skipUserTask = false;
if (StringUtils.isNotEmpty(activeTaskSkipExpression)) {
Expression skipExpression = expressionManager.createExpression(activeTaskSkipExpression);
skipUserTask = SkipExpressionUtil.isSkipExpressionEnabled(execution, skipExpression)
&& SkipExpressionUtil.shouldSkipFlowElement(execution, skipExpression);
}
// Handling assignments need to be done after the task is inserted, to have an id
if (!skipUserTask) {
handleAssignments(taskEntityManager, activeTaskAssignee, activeTaskOwner,
activeTaskCandidateUsers, activeTaskCandidateGroups, task, expressionManager, execution);
}
processEngineConfiguration.getListenerNotificationHelper().executeTaskListeners(task, TaskListener.EVENTNAME_CREATE);
// All properties set, now fire events
if (Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
ActivitiEventDispatcher eventDispatcher = Context.getProcessEngineConfiguration().getEventDispatcher();
eventDispatcher.dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_CREATED, task));
if (task.getAssignee() != null) {
eventDispatcher.dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_ASSIGNED, task));
}
}
if (skipUserTask) {
taskEntityManager.deleteTask(task, null, false, false);
leave(execution);
}
}
二、继承DefaultActivityBehaviorFactory类
public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
@Setter
private WorkTaskAssignRuleService workTaskAssignRuleService;
@Override
public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
BpmUserTaskActivityBehavior bpmUserTaskActivityBehavior =new BpmUserTaskActivityBehavior(userTask);
bpmUserTaskActivityBehavior.setWorkTaskAssignRuleService(workTaskAssignRuleService);
return bpmUserTaskActivityBehavior;
}
}
直接上代码,继承DefaultActivityBehaviorFactory类,重新createUserTaskActivityBehavior方法,使用我们上一步创建的行为类。
三、创建ActivitiConfiguration配置类
@Configuration
public class ActivitiConfiguration{
@Autowired
private DataSource dataSource;
@Bean
public StandaloneProcessEngineConfiguration processEngineConfiguration(BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
StandaloneProcessEngineConfiguration configuration = (StandaloneProcessEngineConfiguration) ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
configuration.setDataSource(dataSource);
configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
return configuration;
}
@Bean
public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(WorkTaskAssignRuleService taskRuleService) {
BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
bpmActivityBehaviorFactory.setWorkTaskAssignRuleService(taskRuleService);
return bpmActivityBehaviorFactory;
}
/**
* 创建引擎
* @return ProcessEngine
*/
@Bean(name = "mysqlProcessEngine")
@Primary
public ProcessEngine processEngine(ProjectModelService projectModelService, BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
return processEngineConfiguration(bpmActivityBehaviorFactory).buildProcessEngine();
}
}
此配置类创建了StandaloneProcessEngineConfiguration流程引擎的配置类,并生成了processEngine引擎类对象,实现使重写的用户任务行为生效。
注:processEngine方法要写bean的name属性,否则会报错,因为springboot默认部署创建引擎对象,会造成bean名称重复,所以加上@Primary注解和@Bean的name属性。
总结
到这里我们工作流程进入到用户任务时,就会触发重写的用户行为方法,根据规则配置的内容,查询到用户,设置到相应属性中,才能实现我们后续的根据用户来查询代办任务功能。