Activiti(四)--流程任务

1 BPMN 2.0任务

BPMN 2.0定义了多种不同的任务,每种任务都有其特定的行为.BPMN2.0中定义的任务有Service Task,Send Task,Receive Task,User Task,Manual Task,Business Rule Task和Script Task

    1.1 任务的继承

任务的继承关系如下图:
在这里插入图片描述

    1.2 任务的类型

ServiceTask:服务任务可以用户调用WebService或者自动执行程序,Activiti中的Java Service Task,Web Sevice Task,Shell Task为BPMN2.0中定义的Service Task,对应的XML元素为serviceTask
Send Task:发送任务表示处理向外部的流程参与人发送消息的工作,在activiti中即可以使用serviceTask配置,也可以使用sendTask来配置
Receive Task:接收任务是一种等待外部流程参与者发送消息的任务,当流程到达该任务时,需要外界告诉该任务接收到消息,它才会继续执行.
User Task:用户任务是典型的流程元素之一,它表示需要有人参与的任务,对应Activiti中的User Task任务.XML元素为userTask
Manual Task:手动任务并不需要任务的流程引擎或者引用的驱动,它会自动执行,在工作流中,它表示一种工作已经完成,工作流引擎不需要关心它是如何完成的.对应的xml元素为manualTask
Business Rule Task:业务规则任务,主要用于向规则引擎嘎松请求参数,让其按照既定的业务规则进行运算并返回结果,当前Activiti只对JBoss的Drools规则引擎提供支持,对应的xml元素为BussinessRuleTask
Script Task:脚本任务用于执行定义好的脚本程序,流程到达该任务后,这些脚本程序会被执行,执行完成后,任务结束,对应xml元素为scriptTask

2 用户任务

    2.1 分配任务候选人

设置任务的候选人可以使用TaskService的addCanidateUser方法或者addCandidateGroup方法,也可以通过如下xml方式配置:
在这里插入图片描述

    2.2 分配任务代理人

一个任务可以有多个候选人,但是只能以后一个代理人.可以使用taskService的setAssignee方法设置任务的代理人,也可以使用如下xml配置文件进行配置:

<userTask id="userTask1" name="task1">
	<humanPerformer>
		<resourceAssignmentExpression>
			<formalExpression>user1</formalExpression>
		</resourceAssignmentExpression>
	</humanPerformer>
</userTask>

    2.3 权限分配扩展

除了使用BPMN2.0定义的xml来分配任务的候选人和代理人,也可以通过Activiti的扩展属性来实现这个功能.代码如下:
在这里插入图片描述

    2.4 使用任务监听器进行任务权限分配

Java代码如下:

public class UserTaskListener implements TaskListener {
	public void notify(DelegateTask delegateTask){
		System.out.println("使用任务监听器设置任务权限");
		delegateTask.setAssignee("use1");
		delegateTask.addCandidateGroup("group1");
		delegateTask.addCandidateUser("user1");
	}
}

xml配置如下:
在这里插入图片描述

    2.5 使用JUEL分配权限

使用juel可以直接调用自定义的JavaBean里面的方法,例如可以使用 o b j e c t . m e t h o d ( ) 或 者 {object.method()}或者 object.method(){object.field}来调用方法或者获取属性值,但是前提是该队行需要被设置到流程参数中.代码如下:

<userTask id="userTask2" name="Task1" activiti:assignee="${authService.getUserAssignee()}"></userTask>
<userTask id="userTask3" name="Task2" activiti:candidateUsers="${authService.getCandidateUsers()}"></userTask>
<userTask id="userTask4" name="Task3" activiti:candidateGroups="${authService.getCandidateGroups()}"></userTask>
<userTask id="userTask5" name="Task4" activiti:assignee="${authService.lastUser}"></userTask>
public class AuthService implements Serializable{
	private String lastUser = "angus";		
	public String getLastUser(){
		return this.lastUser;
	}

	public AuthService(){
		System.out.println("Create AuthService");
	}

	//使用方法为任务指定代理人
	public String getUserAssignee(){
		return "crazyit";
	}

	//使用方法为任务指定候选人
	public List<String> getCandidateUsers(){
		List<String> result = new ArrayList<String>();
		result.add("user1");
		result.add("user2");
		return result;
	}

	//使用方法为任务指定代理人
	public String getCandidateGroups(){
		List<String> result = new ArrayList<String>();
		result.add("group1");
		result.add("group2");
		return result;
	}
}

启动流程时需要将authService设置到流程变量中,如下:

Map<String,Object> vars = new HashMap<String,Object>();
vars.put("authService",new AuthService()):
//启动流程
ProcessInstance pi = runtimeService.startProcessInstanceByKey("process1",vars);
......

3 脚本任务

脚本任务由流程引擎执行,在定义脚本任务时,需要为流程引擎提供它可以解析并执行的脚本语言,流程到达脚本任务时,流程引擎会执行定义好的脚本,任务将会在脚本执行后完成.定义脚本时需要指定脚本的格式(scriptFormat)

    3.1 JavaScript脚本任务

在这里插入图片描述

//部署流程
repository.createDeployment().addClassPathResource("bpmn/JavaScriptTask.bpmn").deploy();
//启动流程
ProcessInstance pi = runtimeService.startProcessInstanceByKey("process1");
//获取在JavaScript中设置的参数
String user = (String)runtimeService.getVariable(pi.getId(),"user");

    3.2 Groovy脚本

<process id="process1" name="process1">
	<startEvent id="startEvent1" name="Start"></startEvent>
	<scriptTask id="scripttask1" name="Script Task" scriptFormat="groovy">
		<script>
			org.crazyit.activiti.GroovyScriptTask.print(execution);
		</script>
	</scriptTask>
	<userTask id="userTask1" name="End Task"></userTask>
	<endEvent id="endevent1" name="End"></endEvent>
	<sequenceFlow id="flow1" name="" sourceRef="startEvent1" targetRef="scripttask1"></sequenceFlow>
	<sequenceFlow id="flow2" name="" sourceRef="scripttask1" targetRef="userTask1"></sequenceFlow>
	<sequenceFlow id="flow3" name="" sourceRef="userTask1" targetRef="endevent1"></sequenceFlow>
</process>
public class GroovyScriptTask{
	public static void print(Execution execution){
		System.out.pringln("Groovy脚本执行:" + execution.getId());
	}

	public static void main(String[] args){
		....
		// 部署流程文件
		repositoryService.createDeployment().addClassPathResource("bpmn/GroovyScriptTask.bpmn").deploy();
		// 启动流程
		ProcessInstance pi = runtimeService.startProcessInstanceByKey("process1");
	}
}

    3.3 设置返回值

在脚本中可以使用execution的setVariable方法设置流程参数,此外直接在脚本中定义的变量,也会被设置为流程参数,如下

<script>
	var user1 = "a";
	var user2 = "b"; 
</script>

对于Groovy脚本,使用以下代码可以设置流程参数:

<script>
	user1 = "a";
	user2 = "b":
</script>

但是使用如下代码,则不能设置流程参数

def user1 = "a";
def user2 = "b";

如果在脚本中想将某些值作为参数设置到流程中,并且想显试的指定变量名称.,则可以使用如下代码:
在这里插入图片描述

//部署流程
repository.createDeployment().addClassPathResource("bpmn/JavaScriptTask.bpmn").deploy();
//启动流程
ProcessInstance pi = runtimeService.startProcessInstanceByKey("process1");
//获取在JavaScript中设置的参数
String user = (String)runtimeService.getVariable(pi.getId(),"user");

    3.4 JUEL脚本

在这里插入图片描述
java代码参见2.5

4 服务任务

服务任务用于请求流程外部的服务或者自动执行程序,Activiti为服务任务提供了三种实现:
Java Service Task, Web Service Task和Shell Task

    4.1 Java服务任务

1)实现JavaDelegate

<process id="process1" name="process1">
	<startEvent id="startEvent1" name="Service Task 1"></startEvent>
	<serviceTask id="serviceTask1" name="Service Task1" activiti:class="org.criazyit.activiti.MyJavaDelegate"></serviceTask>
	<serviceTask id="serviceTask2" name="Service Task2" activiti:class="org.criazyit.activiti.MyJavaDelegate"></serviceTask>
	<endEvent id="endevent1" name="End"></endEvent>
	<sequenceFlow id="flow1" name="" sourceRef="startEvent1" targetRef="serviceTask1"></sequenceFlow>
	<sequenceFlow id="flow2" name="" sourceRef="serviceTask1" targetRef="serviceTask2"></sequenceFlow>
	<sequenceFlow id="flow3" name="" sourceRef="serviceTask2" targetRef="endevent1"></sequenceFlow>
</process>
public class MyJavaDelegate implements JavaDelegate {
	public void execute(DelegateExecution) throws Exception {
		System.out.println("实现JavaDelegate的JavaServiceTask:" + this);
	}
}
public class ImplementServieTask{
	public static void main(String[] args){
		//创建流程引擎
		ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
		//得到流程存储服务组件
		RepositoryService repositoryService = engine.getRepositoryService();
		//得到运行时服务组件
		RuntimeService runtimeService = engine.getRuntimeService();
		//部署流程文件
		repositoryService.createDeployment().addCLasspathResource("bpmn/ImplementServiceTask.bpmn").deploy();		
		//启动流程
		ProcessInstance pi = runtimeService.startProcessInstanceByKey("process1");
	}

}

另一种写法:

<process id="process1" name="process1">
	<startEvent id="startEvent1" name="Service Task 1"></startEvent>
	<serviceTask id="serviceTask1" name="Service Task1" activiti:delegateExpression="${myDelegate}"></serviceTask>
	<serviceTask id="serviceTask2" name="Service Task2" activiti:delegateExpression="${myDelegate}"></serviceTask>
	<endEvent id="endevent1" name="End"></endEvent>
	<sequenceFlow id="flow1" name="" sourceRef="startEvent1" targetRef="serviceTask1"></sequenceFlow>
	<sequenceFlow id="flow2" name="" sourceRef="serviceTask1" targetRef="serviceTask2"></sequenceFlow>
	<sequenceFlow id="flow3" name="" sourceRef="serviceTask2" targetRef="endevent1"></sequenceFlow>
</process>
//创建流程引擎
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
//得到流程存储服务组件
RepositoryService repositoryService = engine.getRepositoryService();
//得到运行时服务组件
RuntimeService runtimeService = engine.getRuntimeService();
//部署流程文件
repositoryService.createDeployment().addCLasspathResource("bpmn/ImplementServiceTask.bpmn").deploy();		
Map<String,Object> vars = new HashMap<String,Object>();
vars.put("myDelegate",new MyJavaDelegate());
//启动流程
ProcessInstance pi = runtimeService.startProcessInstanceByKey("process1");

2)使用普通的JavaBean
代码如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
备注:MyJavaBean必须要实现序列化接口

    4.2 webServiceTask(略)

    4.3 shellTask(略)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值