介绍
在Oracle BPM中如何动态指定审批人,你可能觉得这问题很简单,在UserTask前面加上获取人员的Service就行了,这个也是一般做法,如图
在Service里可以调用第三方接口也可以调用存储过程,但如果这里想调用java代码该如何实现?有两个方案
- 把代码发布成webservice或者rest接口,通过service进行调用
- 借助script组件,script可以执行java代码,如图
把代码发布成webservice,增加了工作量,也增加了系统的复杂度,动态获取审批人问题变成了第三方系统集成问题,script组件的引入污染了流程图,试想如果每个节点都需要同样的计算逻辑,那么在每个节点前面都需要加上script组件,不仅不利于后期维护,而且也会影响最终给用户的流程图,影响流程图的美观。那有办法两者兼得吗,最近在看老外做的一个bpm项目,发现了一个解决方案。
HumanTask配置
- 进入HumanTask->Assignment,点击右上角编辑按钮
- 选择
Use External Routing
,点击编辑进行编辑
- 输入Class Name,具体的Class我们后面创建,可以创建参数,这些参数在Class中可以获取到,可以是静态值也可以是XPath变量,Class必须实现
oracle.bpel.services.workflow.task.IAssignmentService
接口
- 设置完,Assignment的界面是下面这样,并且一些操作也都不可用
代码
配置完HumanTask,就要实现我们的代码
- 在项目右键选择
Project Properties
,进入Libraries and Classpath -> Add Library
找到BPM Services
库
- 点击
Technology Scope
,从左边列表中选择Java
- 在项目上右键
New
创建Java Class
,路径和名称保持HumanTask中配置的一致,必须实现oracle.bpel.services.workflow.task.IAssignmentService
接口,以下是参考
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import oracle.bpel.services.workflow.IWorkflowConstants;
import oracle.bpel.services.workflow.metadata.routingslip.RoutingSlipUtil;
import oracle.bpel.services.workflow.metadata.routingslip.model.*;
import oracle.bpel.services.workflow.metadata.routingslip.model.Participants;
import oracle.bpel.services.workflow.metadata.routingslip.model.ParticipantsType.Participant;
import oracle.bpel.services.workflow.task.IAssignmentService;
import oracle.bpel.services.workflow.task.ITaskAssignee;
import oracle.bpel.services.workflow.task.model.Task;
public class CuxRouting implements IAssignmentService {
@Override
public Participants onInitiation(Task task, Map propertyBag) {
System.out.println("platform===> " + propertyBag.get("platform"));
String approvers=propertyBag.get("platform").toString();
String expirationDays=null;
ObjectFactory objFactory = new ObjectFactory();
Participants participants = objFactory.createParticipants();
Participant participant = objFactory.createParticipantsTypeParticipant();
participant.setName("Participant");
ResourceType resource = objFactory.createResourceType(approvers);
resource.setIsGroup(false);
resource.setIdentityType(IWorkflowConstants.IDENTITY_TYPE_USER);
resource.setType("STATIC");
participant.getResource().add(resource);
participants.getParticipantOrSequentialParticipantOrAdhoc().add(participant);
System.out.println("Routing task to participants\n" +
RoutingSlipUtil.getInstance().toString(participants));
return participants;
}
@Override
public Participants onReinitiation(Task task, Map propertyBag) {
return null;
}
@Override
public Participants onOutcomeUpdated(Task task, Map propertyBag,
String updatedBy, String outcome) {
return null;
}
@Override
public Participants onAssignmentSkipped(Task task, Map propertyBag) {
return null;
}
@Override
public List getAssigneesToRequestForInformation(Task task,
Map propertyBag) {
List rfiUsers = new ArrayList();
return rfiUsers;
}
@Override
public List getReapprovalAssignees(Task task, Map propertyBag,
ITaskAssignee infoRequestedAssignee) {
List reapprovalUsers = new ArrayList();
return reapprovalUsers;
}
}
- 只需实现onInitiation即可,propertyBag可以获取参数,task是当前任务信息,函数需要返回一个Participants对象,该对象记录节点审批类型,审批人等信息,示例代码中将Participants信息打印出来,如下:
<participants xmlns="http://xmlns.oracle.com/bpel/workflow/routingSlip">
<participant name="Participant">
<resource isGroup="false" identityType="user" type="STATIC">DEFINESYS</resource>
</participant>
</participants>
实际上,我们正常配置HumanTask的话,也会包含该信息
所以你可以在HumanTask中配置完,api参考正常配置的就行
部署
- 代码写完正常打包部署即可
思考
这个小功能能用来干嘛呢?这个小功能太有用了,如果你想定制化Oracle BPM,这个特性可以赋予你非常灵活的能力,定制化流程主要是解决两个问题
- 找人问题
- 条件判断问题
该特性可以解决找人问题,注意到onInitiation也传入了Task对象,并且提供了多个接入点函数,这意味着你可以修改该task(这个我没测试过),如果可行的话,那么可以将条件判断的结果存储到Task对象中,在流程中引用解决第二个问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。