工作流引擎JBPM使用

首先获取单例的processEngine对象 默读取"src目录下的jbpm.cfg.xml"的配置文件
 private ProcessEngine processEngine = Configuration.getProcessEngine();
ProcessEngine对象中有一系列的service,这些service是做操作的
一、流程管理
都用的是repositoryService
首先明确这个框架关于部署和流程是如何设计的:
    部署是对象,部署对象中存着生成流程对象的必要属性。
 流程定义是对象,流程定义对象需要解析部署对象中的属性和参数生成。
1.部署对象的生成和持久化
  1..通过xml和png文件生成
    String deploymentId = processEngine.getRepositoryService()//
    .createDeployment()//创建实体
    .addResourceFromClasspath("test/test.jpdl.xml")//给实体设置属性
    .addResourceFromClasspath("test/test.png")//给实体设置属性
    .deploy();
  2..通过zip压缩包生成
    InputStream in = this.getClass().getClassLoader().getResourceAsStream("test/test.zip");
 ZipInputStream zipInputStream = new ZipInputStream(in);
 String deploymentId = processEngine.getRepositoryService()//
    .createDeployment()//
    .addResourcesFromZipInputStream(zipInputStream)//给实体设置属性
    .deploy();
 为什么要返回一个部署的id:
     说白了 部署就是添加,就是通过hibernate往数据库中添加一个部署对象。
  要操作hibernate的对象 显然id是最重要的。
 数据库表中会添加些什么:
  集合表:lob表中会添加一些文件属性 如xml和png 这些属性会有外键参考着某个部署对象
  部署表:deployment表中存着部署对象 由xml和png构成 在lob表中存着 属性在deploymentprop中
  部署属性表:deploymentprop表中存着部署对象的属性
   每个deployment对应该表的四个记录如key、version、id、name等等,该表也外键参考deployment。
2.查询流程定义对象
 流程定义对象需要依靠从数据库查询出的部署对象解析后生成出。
  所以查询流程定义对象就是查询部署对象后解析出流程定义对象。
  所以ProcessDefinition的属性就是deployment的属性如key version id name等等
  key通常用于查询和删除,每次部署时key相同版本不同的部署对象会存在于数据库中
   具体场景为领导规定辞职流程添加了一个环节,则需要新版本的辞职流程,那么
   这个新的流程和旧的流程的key是相同的而版本不同。显示和使用时使用新版本就
   可以了,旧版本的流程定义(部署)也可以删除了。
  而name 通常用于显示 version通常用于过滤最新版本
  id格式为:{key}-{version},是唯一的值 可以用于查询  //key为xml中根目录的key属性
  1..查询所有流程定义对象
 List<ProcessDefinition> list = processEngine.getRepositoryService()//
    .createProcessDefinitionQuery()//
    // .processDefinitionKey("")// 过滤条件
    // .processDefinitionNameLike("")// 过滤条件
    // .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)// 排序条件
    // .orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION)// 排序条件
    // .uniqueResult(); // 执行查询,得到唯一的结果
    // .count(); // 执行查询,得到的是符合条件的总记录数
    // .page(firstResult, maxResults)//
    .list(); // 执行查询,得到结果集合
  2..查询所有最新版本流程定义对象
 List<ProcessDefinition> all = processEngine.getRepositoryService()//
    .createProcessDefinitionQuery()//
    .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)//按版本升序 新版本放在最后面
    .list();
 Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>();
  for (ProcessDefinition pd : all) {
   map.put(pd.getKey(), pd);//放到map中,key为版本号,版本号相同的(map的key相同)被覆盖,最后放入的为最新版
  }
 
3.删除流程定义
 删除流程定义其实就是删除一个部署对象
 String deploymentId = "40001";
  // 删除流程定义,如果有关联的信息,就报错
  processEngine.getRepositoryService().deleteDeployment(deploymentId);
  // 删除流程定义,如果有关联的信息,就同时删除
  processEngine.getRepositoryService().deleteDeploymentCascade(deploymentId);
  // 查询出指定key的所有版本的流程定义
  List<ProcessDefinition> list = processEngine.getRepositoryService()//
    .createProcessDefinitionQuery()//
    .processDefinitionKey(key)//
    .list();

  // 循环删除
  for (ProcessDefinition pd : list) {
   processEngine.getRepositoryService().deleteDeploymentCascade(pd.getDeploymentId());
  }
4.查看流程图和xml
  // 获取某部署对象中所有文件资源的名称
  Set<String> names = processEngine.getRepositoryService().getResourceNames(deploymentId);
 
  // 获取某部署对象中指定名称的文件资源
  proccessDefinition的查询可以拿到上面
  String deploymentId = proccessDefinition.getDeploymentId();
  InputStream in = processEngine.getRepositoryService().getResourceAsStream(deploymentId, resourceName);

二、执行流程实例(执行对象继承流程实例)  
1.启动流程实例 ExecutionService
 public void startProcessInstance() {
  // 使用指定key的最新版本的流程定义来启动一个流程实例(没有key会找name为该值的流程定义启动)
  // 返回的结果是本次启动的流程实例对象
  ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test");
  System.out.println("id=" + pi.getId()//
    + ", state=" + pi.getState()//
    + ", activeActivityNames=" + pi.findActiveActivityNames()// 当前正在执行的活动名称(当前停到哪儿了)
    + ", processDefinitionId=" + pi.getProcessDefinitionId());
 }
 返回的是启动后的流程实例
 数据库表中会添加些什么:
 jbpm4_execution表中为正在执行的流程实例信息 执行该方法会使该表添加记录
 jbpm4_hist_procinst表中为已经执行完的流程实例信息
2.查询我的未完成的任务列表 TaskService()
 jbpm_task 正在执行的任务信息 任务为整个执行流程实例中的一个小的步骤
  是属于某个执行对象的 该表中会有从哪提交来往哪提交去等字段
 jbpm_hist_task 已经执行完的任务信息 也就是 已经完成的小步骤信息
 @Test
 public void findMyPersonalTaskList() {
  // String userId = "员工";
  // String userId = "部门经理";
  String userId = "总经理";

  // 查询
  // List<Task> list = processEngine.getTaskService().findPersonalTasks(userId);
  List<Task> list = processEngine.getTaskService()//
    .createTaskQuery()// 这样查询可以支持分页
    .assignee(userId)// 指定办理人条件
    .orderAsc(TaskQuery.PROPERTY_NAME)// 指定排序条件
    // .uniqueResult();//查出本流程实例当前仅有的任务
    // .count();
    // .page(firstResult, maxResults)
    .list();

  // 显示
  System.out.println("================= 【" + userId + "】的任务列表 ================");
  for (Task task : list) {
   System.out.println("id=" + task.getId()// 任务的id
     + ",name=" + task.getName()// 任务的名称
     + ",assginee=" + task.getAssignee()// 任务的办理人
     + ",createTime=" + task.getCreateTime()// 任务的创建
     + ",executionId=" + task.getExecutionId()); // 任务所属的执行流程实例对象的id
  }
 }
3.办理完一个任务 TaskService()
  List<Task> list = processEngine.getTaskService()//
  .createTaskQuery()// 这样查询可以支持分页
  .processInstanceId()//通过流程定义过滤
  .uniqueResult();//查出本流程实例当前仅有的任务
  String taskId = "130001";
  processEngine.getTaskService().completeTask(taskId);

三、流程变量
1.为流程实例对象设置流程变量
 String executionId = "test.110001";//流程实例对象的id
 String name = "请假天数";
 String value = "10天";
 processEngine.getExecutionService().setVariable(executionId, name, value);
 LeaveForm form = new LeaveForm();//form为hibernate的持久化对象
 form.setId(1L); // 模拟一条游离状态的对象
 form.setData("张三请假3天");
 processEngine.getExecutionService().setVariable(executionId, "form", form);
2.获取流程变量
 String executionId = "test.110001";
 String variableName = "请假天数";
 String value = (String) processEngine.getExecutionService().getVariable(executionId, variableName);
 System.out.println("变量:" + variableName + " = " + value);
 LeaveForm value = (LeaveForm) processEngine.getExecutionService().getVariable(executionId, "form");
3.设置map类型的流程变量 map的key为String也就是变量名 value为对象或者普通类型的变量值
 1..使用指定key的最新版本的流程定义来启动一个流程实例,并设置一些流程变量
 processEngine.getExecutionService().startProcessInstanceByKey(pdKey, variablesMap);
 2..办理完一个任务,并设置一些流程变量
 processEngine.getTaskService().completeTask(taskId, variablesMap);
 3..通过Execution设置一个流程变量
 processEngine.getExecutionService().setVariable(executionId, name, value);
 4..通过Execution设置多个流程变量(Map)
 processEngine.getExecutionService().setVariables(executionId, variablesMap);
 5..通过Task向所属的Execution中设置多个流程变量(Map)
 processEngine.getTaskService().setVariables(taskId, variablesMap);
4.获取流程变量
 1..获取指定Execution中的一个流程变量
 processEngine.getExecutionService().getVariable(executionId, variableName);
 2..获取指定Execution中的所有流程变量名称
 Set<String> variableNames = processEngine.getExecutionService().getVariableNames(executionId);
 3..获取指定Execution中的指所有定名称的流程变量
 Map<String, Object> map = processEngine.getExecutionService().getVariables(executionId, variableNames);
 processEngine.getTaskService().getVariable(taskId, variableName);
 processEngine.getTaskService().getVariableNames(taskId);
 processEngine.getTaskService().getVariables(taskId, variableNames);

三、流程图
 1.transition
 transition其实就是个带方向的线
 name属性 如 name="to 总经理审批" 是它最重要的属性 to xxx决定它指向的下一个活动
 用到transition的方法有两种情况
  1.1第一种 当完成一个任务活动时 指定下一个活动
  String outcome = "to 总经理审批";
  processEngine.getTaskService().completeTask(task.getId(), outcome);
  1.2第二种 让Execution向后执行一步 指定下一个活动
  processEngine.getExecutionService().signalExecutionById(executionId, signalName);
 2.activity
 activity就是图中的一个节点 这些节点有些是预定义的 如
  2.1预定义活动
  Start  开始活动
   代表流程的开始边界,一个流程有且只能有一个Start活动。
   开始活动只能指定一个Transition。
   在流程实例启动后,会自动的使用这个唯一的Transition离开开始活动,到一下个活动。
  End   结束活动
   代表流程的结束边界,可以有多个,也可以没有。
   如果有多个,则到达任一个结束活动,整个流程就都结束了;
   如果没有,则到达最后那个没有Transition的活动,流程就结束了。
  State  状态活动
   让流程在该活动等待,直到调用signalExecutionById方法指定transition离开这个状态活动
   processEngine.getExecutionService().signalExecutionById(executionId, transitionName);
  Decision 判断活动
   可以直接指定expression属性,如:expr="#{'to state2'}" 这是从流程变量中取值
   也可以在它的class属性中指定一个实现了DecisionHandler接口的类
    public String decide(OpenExecution execution)
    从传入参数中获取流程变量 进行判断后 返回transition的名字
   如果同时配置了expression与Handler,则expression有效,忽略Handler。
  Fork/Join 分支/聚合活动
   这是多个分支并行(同时)执行的,并且所有的分支Execution都到Join活动后才离向后执行。
   只有一个name属性。
  Task  任务活动
   个人任务
    指定办理人
    直接指定或使用流程变量,例:assignee="张三"、assignee="#{employee}"
    使用AssignmentHandler需要在xml文件中修改
     <task g="74,145,92,52" name="经理审批">
      <assignment-handler class="cn.itcast.i_personaltask_2.AssignmentHandlerImpl"></assignment-handler>
      <transition g="-45,-6" name="to end1" to="end1" />
     </task>
     写类实现AssignmentHandler接口
     assign(Assignable assignable, OpenExecution execution)
     通过execution获得流程变量 计算出办理人 设置到assignable.setAssignee(userId);
    直接在代码中修改Task的assignee属性:TaskService.assignTask(taskId, userId);
   组任务
   组任务生成后每个办理组中组中的办理人都能看到该任务 通过 拾取将其变为该成员的个人任务 此时组中其他成员看不到该任务
    指定办理人组
    直接指定或使用流程变量,例:assignee="小A,小B,小C"、assignee="#{userIds}"(userIds是一个字符串,例:"小A,小B,小C,小D")
    使用AssignmentHandler:assignable.addCandidateUser(userId);指定本任务的候选人 执行多次
   组任务的分配(拾取)与退回
    String taskId = "310008";
    String userId = "小B";
    processEngine.getTaskService().takeTask(taskId, userId);//分配组任务
    processEngine.getTaskService().assignTask(taskId, null);//退回组任务
  自定义活动
   <custom name="发短信通知" g="71,131,92,52" class="cn.itcast.k_custom.ExternalActivityBehaviourImpl">
    <transition name="to end1" to="end1" g="-48,-10"/>
   </custom>
   class中的类实现了ExternalActivityBehaviour接口
   public void execute(ActivityExecution execution)
    execution.takeDefaultTransition(); //使用默认的transition离开该活动
    execution.take(transitionName);//使用指定transition离开该活动
    execution.waitForSignal();//执行完本方法后不要离开当前活动,而是在调用sigalExecution..()时才离开
   public void signal(ActivityExecution execution, String signalName, Map<String, ?> parameters)
    //如果在当前活动中暂停了,在调用sigalExecution..()离开当前活动之前执行的代码
 3.Event 事件
  在task或者其他活动节点中指定该标签 表示该活动节点在进入和离开的时候会被监听到并执行一些逻辑
  <on event="end">
   <event-listener class="cn.itcast.l_event.EventListenerImpl"/>
  </on>
  <on event="start">
   <event-listener class="cn.itcast.l_event.EventListenerImpl"/>
  </on>
  EventListenerImpl类实现EventListener接口
   notify(EventListenerExecution execution)//该方法会被执行
   
一般在页面中遍历的是ProcessDefinition对象 所以可以方便的拿到processDefinitionId 通过查询流程定义 拿到流程定义后增删改查就能做了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
jbpm是一个开源的Java工作引擎,它提供了一个框架和工具,用于定义、执行和管理业务程。jbpm的持久层采用hibernate3来实现,这是因为jbpm的靠山是jboss,而hibernate是jboss的一个重要组成部分,因此选择了hibernate作为持久层的实现方式。 jbpm工作引擎具有以下特点: . 灵活性:jbpm允许用户通过定义程模型和规则来灵活地定义和修改业务程。它支持基于图形化的程设计器,使得程定义更加直观和易于理解。 2. 可扩展性:jbpm提供了丰富的扩展点和插件机制,可以根据具体需求进行定制和扩展。用户可以自定义各种节点类型、执行器、监听器等,以满足不同的业务场景。 3. 可视化:jbpm提供了一个基于Web的控制台,用于监控和管理运行中的程实例。用户可以实时查看程状态、任务列表、程历史等信息,方便进行程管理和优化。 4. 高性能:jbpm采用了基于事件驱动的执行模型,能够高效地处理大量的并发程实例。它支持异步执行、并行分支、定时器等功能,提供了良好的性能和可伸缩性。 5. 可靠性:jbpm具有良好的事务管理和异常处理机制,能够保证程执行的一致性和可靠性。它支持分布式部署和集群模式,提供了高可用性和容错性。 总结起来,jbpm是一个功能强大、灵活可扩展的Java工作引擎,适用于各种业务场景和规模的程管理需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值