任务监听器用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式
注意:assignment事件比create先执行。
实现接口org.activiti.engine.delegate.TaskListener
在流程定义文件中用class属性来指定该监听器
/**
* @author Tom Baeyens
*/
public interface TaskListener extends Serializable {
//create(创建):当任务已经创建,并且所有任务参数都已经设置时触发
String EVENTNAME_CREATE = "create";
/**assignment(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,
create事件触发前,首先触发assignment事件。这看起来不是自然顺序,
但是有实际原因的:当收到create事件时,我们通常希望查看任务的所有参数,包括办理人。**/
String EVENTNAME_ASSIGNMENT = "assignment";
//(完成):当任务已经完成,从运行时数据中删除前触发
String EVENTNAME_COMPLETE = "complete";
//(删除):在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发
String EVENTNAME_DELETE = "delete";
/**
* Not an actual event, used as a marker-value for {@link TaskListener}s that should be called for all events,
* including {@link #EVENTNAME_CREATE}, {@link #EVENTNAME_ASSIGNMENT} and {@link #EVENTNAME_COMPLETE} and {@link #EVENTNAME_DELETE}.
*/
String EVENTNAME_ALL_EVENTS = "all";
void notify(DelegateTask delegateTask);
}
xml文件中定义
任务监听器中我们可以拿到DelegateTask对象,这个对象可以让我们操作activiti引擎中的一些东西,下面看一下DelegateTask类中的定义主要访法。
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
/**
* 任务监听器用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式
*
* 任务监听器支持下列属性:
* event(事件)(必填):任务监听器将被调用的任务事件类型。可用的事件有:
* create(创建):当任务已经创建,并且所有任务参数都已经设置时触发。
* assignment(指派):当任务已经指派给某人时触发。请注意:当流程执行到达用户任务时,create事件触发前,首先触发
* assignment事件。这看起来不是自然顺序,但是有实际原因的:当收到create事件时,我们通常希望查看任务的所有参数,包括
* 办理人。
* complete(完成):当任务已经完成,从运行时数据中删除前触发。
* delete(删除):在任务即将被删除前触发。请注意当任务通过completeTask正常完成时也会触发
*
* class:需要调用的代理类。这个类必须实现 org.activiti.engine.delegate.TaskListener 接口
*
*
* expression:(不能与class属性一起使用):指定在事件发生时要执行的表达式。可以为被调用的对象传递 DelegateTask 对象与事件名(使用 task.eventName )作为参数
*
*
*
* delegateExpression:可以指定一个能够解析为 TaskListener 接口实现类对象的表达式。与服务任务类似
*
*
*/
@Slf4j
public class SiteReportUserTask implements TaskListener {
private static final long serialVersionUID = 3654543511891213996L;
@Override
public void notify(DelegateTask delegateTask) {
log.info("creattime: {}",delegateTask.getCreateTime());
log.info("getProcessInstanceId: {}",delegateTask.getProcessInstanceId());
log.info("数据库中的taskId主键: {}",delegateTask.getId());
log.info("任务名称: {}",delegateTask.getName());
delegateTask.setName("修改任务名称");
log.info("获取任务的描述信息: {}",delegateTask.getDescription());
delegateTask.setDescription("修改任务的描述信息");
/**
* lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high
* [80..100] highest
任务处理的优先级范围是0-100
*/
log.info("任务处理的优先级范围是0-100: {}",delegateTask.getPriority());
delegateTask.setPriority(1); /** 修改优先级*/
log.info("获取流程实例id: {}",delegateTask.getProcessInstanceId());
log.info("获取流程获取执行id: {}",delegateTask.getExecutionId());
log.info("获取流程定义id: {}",delegateTask.getProcessDefinitionId());
/** 添一个加候选人 */
//void addCandidateUser(String userId);
/** 添加候选人集合 */
//void addCandidateUsers(Collection candidateUsers);
/** 添加候选组 */
//void addCandidateGroup(String groupId);
String eventName = delegateTask.getEventName();
if (EVENTNAME_CREATE.endsWith(eventName)) {
System.out.println("create=========");
}else if (EVENTNAME_ASSIGNMENT.endsWith(eventName)) {
System.out.println("assignment========");
}else if (EVENTNAME_COMPLETE.endsWith(eventName)) {
System.out.println("complete===========");
}else if (EVENTNAME_DELETE.endsWith(eventName)) {
System.out.println("delete=============");
}
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.engine.delegate;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType;
/**
* @author Joram Barrez
*/
public interface DelegateTask extends VariableScope {
/** DB id of the task. */
String getId();
/** Name or title of the task. */
String getName();
/** Change the name of the task. */
void setName(String name);
/** Free text description of the task. */
String getDescription();
/** Change the description of the task */
void setDescription(String description);
/** indication of how important/urgent this task is with a number between
* 0 and 100 where higher values mean a higher priority and lower values mean
* lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high
* [80..100] highest */
int getPriority();
/** indication of how important/urgent this task is with a number between
* 0 and 100 where higher values mean a higher priority and lower values mean
* lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high
* [80..100] highest */
void setPriority(int priority);
/** Reference to the process instance or null if it is not related to a process instance. */
String getProcessInstanceId();
/** Reference to the path of execution or null if it is not related to a process instance. */
String getExecutionId();
/** Reference to the process definition or null if it is not related to a process. */
String getProcessDefinitionId();
/** The date/time when this task was created */
Date getCreateTime();
/** The id of the activity in the process defining this task or null if this is not related to a process */
String getTaskDefinitionKey();
/** Indicated whether this task is suspended or not. */
boolean isSuspended();
/** The tenant identifier of this task */
String getTenantId();
/** The form key for the user task */
String getFormKey();
/** Change the form key of the task */
void setFormKey(String formKey);
/** Returns the execution currently at the task. */
DelegateExecution getExecution();
/** Returns the event name which triggered the task listener to fire for this task. */
String getEventName();
/** The current {@link org.activiti.engine.task.DelegationState} for this task. */
DelegationState getDelegationState();
/** Adds the given user as a candidate user to this task. */
void addCandidateUser(String userId);
/** Adds multiple users as candidate user to this task. */
void addCandidateUsers(Collection candidateUsers);
/** Adds the given group as candidate group to this task */
void addCandidateGroup(String groupId);
/** Adds multiple groups as candidate group to this task. */
void addCandidateGroups(Collection candidateGroups);
/** The {@link User.getId() userId} of the person responsible for this task. */
String getOwner();
/** The {@link User.getId() userId} of the person responsible for this task.*/
void setOwner(String owner);
/** The {@link User.getId() userId} of the person to which this task is delegated. */
String getAssignee();
/** The {@link User.getId() userId} of the person to which this task is delegated. */
void setAssignee(String assignee);
/** Due date of the task. */
Date getDueDate();
/** Change due date of the task. */
void setDueDate(Date dueDate);
/** The category of the task. This is an optional field and allows to 'tag' tasks as belonging to a certain category. */
String getCategory();
/** Change the category of the task. This is an optional field and allows to 'tag' tasks as belonging to a certain category. */
void setCategory(String category);
/**
* Involves a user with a task. The type of identity link is defined by the given identityLinkType.
* @param userId id of the user involve, cannot be null.
* @param identityLinkType type of identityLink, cannot be null (@see {@link IdentityLinkType}).
* @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
*/
void addUserIdentityLink(String userId, String identityLinkType);
/**
* Involves a group with group task. The type of identityLink is defined by the given identityLink.
* @param groupId id of the group to involve, cannot be null.
* @param identityLinkType type of identity, cannot be null (@see {@link IdentityLinkType}).
* @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
*/
void addGroupIdentityLink(String groupId, String identityLinkType);
/**
* Convenience shorthand for {@link #deleteUserIdentityLink(String, String)}; with type {@link IdentityLinkType#CANDIDATE}
* @param userId id of the user to use as candidate, cannot be null.
* @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
*/
void deleteCandidateUser(String userId);
/**
* Convenience shorthand for {@link #deleteGroupIdentityLink(String, String, String)}; with type {@link IdentityLinkType#CANDIDATE}
* @param groupId id of the group to use as candidate, cannot be null.
* @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
*/
void deleteCandidateGroup(String groupId);
/**
* Removes the association between a user and a task for the given identityLinkType.
* @param userId id of the user involve, cannot be null.
* @param identityLinkType type of identityLink, cannot be null (@see {@link IdentityLinkType}).
* @throws ActivitiObjectNotFoundException when the task or user doesn't exist.
*/
void deleteUserIdentityLink(String userId, String identityLinkType);
/**
* Removes the association between a group and a task for the given identityLinkType.
* @param groupId id of the group to involve, cannot be null.
* @param identityLinkType type of identity, cannot be null (@see {@link IdentityLinkType}).
* @throws ActivitiObjectNotFoundException when the task or group doesn't exist.
*/
void deleteGroupIdentityLink(String groupId, String identityLinkType);
/**
* Retrieves the candidate users and groups associated with the task.
* @return set of {@link IdentityLink}s of type {@link IdentityLinkType#CANDIDATE}.
*/
Set getCandidates();
}
使用activiti:taskListener
元素的expression属性来指定监听器
package org.jeecg.modules.activiti.ext.expression;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import java.io.Serializable;
@Slf4j
public class TaskListenerExpression implements Serializable {
private static final long serialVersionUID = 6880733208262796584L;
public void execute(DelegateTask delegateTask) {
log.info("creattime: {}", delegateTask.getCreateTime());
log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());
log.info("数据库中的taskId主键: {}", delegateTask.getId());
log.info("任务名称: {}", delegateTask.getName());
delegateTask.setName("修改任务名称");
log.info("获取任务的描述信息: {}", delegateTask.getDescription());
delegateTask.setDescription("修改任务的描述信息");
/**
* lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high
* [80..100] highest
任务处理的优先级范围是0-100
*/
log.info("任务处理的优先级范围是0-100: {}", delegateTask.getPriority());
delegateTask.setPriority(1); /** 修改优先级*/
log.info("获取流程实例id: {}", delegateTask.getProcessInstanceId());
log.info("获取流程获取执行id: {}", delegateTask.getExecutionId());
log.info("获取流程定义id: {}", delegateTask.getProcessDefinitionId());
/** 添一个加候选人 */
//void addCandidateUser(String userId);
/** 添加候选人集合 */
//void addCandidateUsers(Collection candidateUsers);
/** 添加候选组 */
//void addCandidateGroup(String groupId);
String eventName = delegateTask.getEventName();
if (TaskListener.EVENTNAME_CREATE.endsWith(eventName)) {
System.out.println("create=========");
} else if (TaskListener.EVENTNAME_ASSIGNMENT.endsWith(eventName)) {
System.out.println("assignment========");
} else if (TaskListener.EVENTNAME_COMPLETE.endsWith(eventName)) {
System.out.println("complete===========");
} else if (TaskListener.EVENTNAME_DELETE.endsWith(eventName)) {
System.out.println("delete=============");
}
}
}
在流程执行到某个阶段,或者启动流程实例的时候,用下面代码调用
Map map=new HashMap<>();
map.put("taskListenerExpression",new TaskListenerExpression());
runtimeService.startProcessInstanceByKey("taskListener_study2",map);
spring表达式只是对4.1的优化处理,我们只需要在自己定义的TaskListenerExpression类上加注解管理该bean。在表达式中直接调用。如下其他都不用改表:
@Slf4j
@Service("listenerSpringExpression")
public class TaskListenerExpression implements Serializable {
private static final long serialVersionUID = 6880733208262796584L;
public void execute(DelegateTask delegateTask) {
log.info("creattime: {}", delegateTask.getCreateTime());
log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());
xml处的调用也不需要改变。当任务执行到该节点的时候,会直接调用该spring管理的bean。
委托表达式 和 表达式区别:
(1)委托表达式需要实现TaskListener和序列化接口
(2)xml中直接写实现类的变量名,不用写方法名称,默认调取接口方法名
package org.jeecg.modules.activiti.ext.expression;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import java.io.Serializable;
/**
* 监听器 委托表达式的实现
*/
@Slf4j
public class TaskListenerDelegateExpression implements TaskListener,Serializable {
private static final long serialVersionUID = 6880733208262796584L;
public void notify(DelegateTask delegateTask) {
log.info("creattime: {}", delegateTask.getCreateTime());
log.info("getProcessInstanceId: {}", delegateTask.getProcessInstanceId());
log.info("数据库中的taskId主键: {}", delegateTask.getId());
log.info("任务名称: {}", delegateTask.getName());
delegateTask.setName("修改任务名称");
log.info("获取任务的描述信息: {}", delegateTask.getDescription());
delegateTask.setDescription("修改任务的描述信息");
/**
* lower priority: [0..19] lowest, [20..39] low, [40..59] normal, [60..79] high
* [80..100] highest
任务处理的优先级范围是0-100
*/
log.info("任务处理的优先级范围是0-100: {}", delegateTask.getPriority());
delegateTask.setPriority(1); /** 修改优先级*/
log.info("获取流程实例id: {}", delegateTask.getProcessInstanceId());
log.info("获取流程获取执行id: {}", delegateTask.getExecutionId());
log.info("获取流程定义id: {}", delegateTask.getProcessDefinitionId());
/** 添一个加候选人 */
//void addCandidateUser(String userId);
/** 添加候选人集合 */
//void addCandidateUsers(Collection candidateUsers);
/** 添加候选组 */
//void addCandidateGroup(String groupId);
String eventName = delegateTask.getEventName();
if (TaskListener.EVENTNAME_CREATE.endsWith(eventName)) {
System.out.println("create=========");
} else if (TaskListener.EVENTNAME_ASSIGNMENT.endsWith(eventName)) {
System.out.println("assignment========");
} else if (TaskListener.EVENTNAME_COMPLETE.endsWith(eventName)) {
System.out.println("complete===========");
} else if (TaskListener.EVENTNAME_DELETE.endsWith(eventName)) {
System.out.println("delete=============");
}
}
}
在流程到达该任务节点时,就会从流程变量中获取taskListenerDelegateExpression,并执行notify方法
Map map=new HashMap<>();
map.put("taskListenerDelegateExpression",new TaskListenerDelegateExpression());
runtimeService.startProcessInstanceByKey("taskListener_study2",map);
通过多次设置字段的值可以得知:
fieldNameA取值优先级: 第1个 字符串>第3个 字符串> 第二个 表达式
@Slf4j
public class SiteReportUserTask implements TaskListener {
private static final long serialVersionUID = 3654543511891213996L;
private Expression fieldNameA;
@Override
public void notify(DelegateTask delegateTask) {
Object o=fieldNameA.getValue(delegateTask);
String str=fieldNameA.getExpressionText();
... ...
若在表达式中输入:${1==1},则上述代码输出是:o:true;str:${1==1}。自己体会,一个是值,一个是内容字符串。