• 1. 北京传智播客教育 www.itcast.cnJBPM4.4工作流
  • 2. 北京传智播客教育 www.itcast.cnJBPM入门
  • 3. 北京传智播客教育 www.itcast.cnJBPM入门工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。 通俗的说,流程就是多个人在一起合作完成某件事情的步骤,把步骤变成计算机能理解的形式就是工作流。
  • 4. 北京传智播客教育 www.itcast.cnJBPM入门工作流管理系统(WfMS,Workflow Management System)的主要功能是通过计算机技术的支持去定义、执行和管理工作流,协调工作流执行过程中工作之间以及群体成员之间的信息交互。应能提供以下三个方面的功能支持: 1、定义工作流:包括具体的活动、规则等 2、运行控制功能:在运行环境中管理工作流过程,对工作流过程中的活动进行调度 3、运行交互功能:指在工作流运行中,WfMS与用户(活动的参与者)及外部应用程序工具交互的功能。工作流主要实现功能一、定义工作流 二、执行工作流 Swing/AWT +Applet、javascript、flex 顺序、分支、聚合、并发…
  • 5. 北京传智播客教育 www.itcast.cnJBPM入门采用工作流管理系统的优点 1、提高系统的柔性,适应业务流程的变化  2、实现更好的业务过程控制,提高顾客服务质量 3、降低系统开发和维护成本 工作流框架有:Jbpm、OSWorkflow、ActiveBPEL、YAWL等。工作流系统的优点:
  • 6. 北京传智播客教育 www.itcast.cnJBPM入门jBPM 即java Business Process Management,是基于java的业务流程管理系统。jBPM是市面上相当流行的一款开源工作流引擎,引擎底层基于Active Diagram模型。jBPM4.4使用了hibernate(3.3.1版),因此可以很好的支持主流数据库。jBPM4.4共有18张表,用于存储业务流程数据。 jBPM官方主页:http://www.jboss.org/jbpm开源工作流JBPM4.4介绍:
  • 7. 北京传智播客教育 www.itcast.cnJBPM入门JBPM4.4操作流程
  • 8. 北京传智播客教育 www.itcast.cn准备JBPM环境
  • 9. 北京传智播客教育 www.itcast.cn准备JBPM环境JBPM所需环境 1、jBPM requires a JDK (standard java) version 5 or higher. http://java.sun.com/javase/downloads/index.jsp 2、To execute the ant scripts, you'll need apache ant version 1.7.0 or higher: http://ant.apache.org/bindownload.cgi 下载相关资源 1、jBPM下载地址:http://sourceforge.net/projects/jbpm/files/ 2、Eclipse下载地址( Eclipse IDE for Java EE Developers (163 MB),Version:3.5 ):http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo
  • 10. 北京传智播客教育 www.itcast.cn准备JBPM环境安装流程设计器(GPD,Eclipse插件 ) GPD(Graphical Process Designer)是一个Eclipse插件。 路径为:JBPM_HOME/ install/src/gpd/jbpm-gpd-site.zip 。 安装方法说明(jBPM4.4User Guide, 2.11.2. Install the GPD plugin into eclipse): Help --> Install New Software... Click Add... In dialog Add Site dialog, click Archive... Navigate to install/src/gpd/jbpm-gpd-site.zip and click 'Open' Clicking OK in the Add Site dialog will bring you back to the dialog 'Install' Select the jPDL 4 GPD Update Site that has appeared Click Next... and then Finish Approve the license Restart eclipse when that is asked
  • 11. 北京传智播客教育 www.itcast.cn准备JBPM环境查看是否成功安装了插件:WindowPreference中是否有Jboss jBPM项
  • 12. 北京传智播客教育 www.itcast.cn准备JBPM环境在Eclipse中添加jPDL4.4 Schema校验 流程定义文件的xsd文件的路径为:JBPM_HOME/src/jpdl-4.4.xsd。 添加到Eclipse中的方法为(jBPM4.4 User Guide, 2.11.5. Adding jPDL 4 schema to the catalog): Click Window --> Preferences Select XML --> XML Catalog Click 'Add...' The 'Add XML Catalog Entry' dialog opens Click the button with the map-icon next to location and select 'File System...' In the dialog that opens, select file jpdl-4.4.xsd in the src directory of the jBPM installation root. Click 'Open' and close all the dialogs
  • 13. 北京传智播客教育 www.itcast.cn准备JBPM环境
  • 14. 北京传智播客教育 www.itcast.cn准备JBPM环境准备JPBM的开发环境 1、${JBPM_HOME}/jbpm.jar(核心包) 2、JBPM_HOME/lib/*.jar,不添加以下jar包:servlet-api.jar, junit.jar。其中junit.jar一定不要添加,因为是3.8.2版本,与我们使用的junit4有冲突。 3、由于slf4j-jdk14.jar、slf4j-log4j12.jar都具有处理日志的功能,会避免出现冲突,所以可去掉slf4j-jdk14.jar。 4、所使用的数据库对应的驱动的jar包(第2步所添加的jar包中已包含mysql的jdbc驱动jar包)。
  • 15. 北京传智播客教育 www.itcast.cn准备JBPM环境添加并定制配置文件 1、配置文件可以从JBPM_HOME/examples/src/中拷贝: jbpm.cfg.xml、 logging.properties(拷贝hibernate包下/project/etc/log4j.properties即可)、 jbpm.hibernate.cfg.xml。 2、修改logging.properties中的日志输出级别为Error: log4j.rootLogger=ERROR, stdout 3、修改jbpm.hibernate.cfg.xml中的数据库连接信息。如果使用MySql,使用的方言一定要是org.hibernate.dialect.MySQL5InnoDBDialect。 4、数据库连接编码一定要是UTF-8。否则可能会在部署含有中文字符的流程定义时会抛异常,说sql语法错误。 5、连接数据库的时候,建议使用   jdbc:mysql://localhost:3306/itcastjbpm?useUnicode=true&characterEncoding=utf8可防止存储到数据库的值是乱码 注意:如使用MySQLDialect,就会在流程实例结束时抛异常:com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`jbpm44_20101028/jbpm4_execution`, CONSTRAINT `FK_EXEC_INSTANCE` FOREIGN KEY (`INSTANCE_`) REFERENCES `jbpm4_execution` (`DBID_`))。。
  • 16. 北京传智播客教育 www.itcast.cn准备JBPM环境初始化数据库 方法一:执行sql脚本文件${JBPM4.4_HOME}/install/src/db/create/jbpm.*.create.sql 方法二:使用Hibernate的自动建表,在jbpm.hibernate.cfg.xml中配置:hibernate.hbm2ddl.auto=update。 可以初始化程序创建表,例如: public void testCreateSchema() { // hbm2ddl.auto=update new org.hibernate.cfg.Configuration().configure("jbpm.hibernate.cfg.xml").buildSessionFactory(); }
  • 17. 北京传智播客教育 www.itcast.cn第一章:JPBM程序 ——HelloWorld
  • 18. 北京传智播客教育 www.itcast.cnJPBM程序——HelloWorld流程图
  • 19. 北京传智播客教育 www.itcast.cnJPBM程序——HelloWorld建表并创建流程引擎对象(核心对象) // 建表 @Test public void testCreateSchema() { // hbm2ddl.auto=update new org.hibernate.cfg.Configuration().configure("jbpm.hibernate.cfg.xml").buildSessionFactory(); } private ProcessEngine processEngine = new Configuration().setResource("jbpm.cfg.xml").buildProcessEngine(); 流程引擎(工作流核心对象)
  • 20. 北京传智播客教育 www.itcast.cnJPBM程序——HelloWorld部署流程定义 // 1,部署流程定义 @Test public void testDeployProcessDefinition() throws Exception { processEngine.getRepositoryService()// .createDeployment()// .addResourceFromClasspath("helloworld/helloworld.jpdl.xml")// .addResourceFromClasspath("helloworld/helloworld.png")// .deploy(); }
  • 21. 北京传智播客教育 www.itcast.cnJPBM程序——HelloWorld启动流程实例 // 2,启动流程实例 @Test public void testStartProcessInstance() throws Exception { ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("helloworld"); System.out.println("流程实例启动成功!id="+pi.getId() + "name="+pi.getName() + "key="+pi.getKey()+ "getProcessDefinitionId="+pi.getProcessDefinitionId()); }
  • 22. 北京传智播客教育 www.itcast.cnJPBM程序——HelloWorld查询我的任务列表(未办理) // 3,查询我的未办理的任务列表 @Test public void testFindMyTaskList() throws Exception { // 查询 // String userId = "员工"; // String userId = "部门经理"; String userId = "总经理"; List taskList = processEngine.getTaskService().findPersonalTasks(userId); // 显示 System.out.println("=========== 【" + userId + "】的任务列表 ==========="); for (Task task : taskList) { System.out.println("id=" + task.getId() + ", name=" + task.getName() + ", assignee=" + task.getAssignee()); } }
  • 23. 北京传智播客教育 www.itcast.cnJPBM程序——HelloWorld办理任务 // 4,办理任务 @Test public void testCompleteTask() throws Exception { String taskId = "50001"; processEngine.getTaskService().completeTask(taskId); }
  • 24. 北京传智播客教育 www.itcast.cn第二章:流程定义管理CRUD
  • 25. 北京传智播客教育 www.itcast.cn流程定义管理CRUD流程图
  • 26. 北京传智播客教育 www.itcast.cn流程定义管理CRUD创建流程引擎的3种方式 第一种:使用默认的配置文件(jbpm.cfg.xml)生成Configuration并构建ProcessEngine: ProcessEngine processEngine = new Configuration().buildProcessEngine(); 第二种:使用指定的配置文件(要放到classPath下): ProcessEngine processEngine = new Configuration() .setResource("my-own-configuration-file.xml") .buildProcessEngine(); 第三种:使用如下代码获取使用默认配置文件的、单例的ProcessEngine对象: ProcessEngine processEngine = Configuration.getProcessEngine();
  • 27. 北京传智播客教育 www.itcast.cn流程定义管理CRUD部署流程定义 // 部署 @Test public void testDeploy() throws Exception { String deploymentId = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromClasspath("helloworld/helloworld.jpdl.xml")// .addResourceFromClasspath("helloworld/helloworld.png")// .deploy(); System.out.println("deploymentId=" + deploymentId); } // 部署 @Test public void testDeploy_zip() throws Exception { InputStream in = getClass().getClassLoader().getResourceAsStream( "helloworld/helloworld.zip"); ZipInputStream zipInputStream = new ZipInputStream(in); String deploymentId = processEngine.getRepositoryService()// .createDeployment()// .addResourcesFromZipInputStream(zipInputStream)// .deploy(); System.out.println("deploymentId=" + deploymentId); }
  • 28. 北京传智播客教育 www.itcast.cn流程定义管理CRUD查询流程定义 // 查询所有 @Test public void testFindAll() throws Exception { // 查询 List list = processEngine.getRepositoryService()// .createProcessDefinitionQuery()// // 过滤条件 // .processDefinitionId("helloworld-1")// .processDefinitionKey("helloworld")// // 排序 // .orderAsc(ProcessDefinitionQuery.PROPERTY_ID)// // .orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION)// // 执行查询 // .uniqueResult(); // .count(); // .page(firstResult, maxResults)// .list(); // 显示 for (ProcessDefinition pd : list) { System.out.println("id=" + pd.getId()// 格式:{key}-{version} + ", name=" + pd.getName()// .jpdl.xml根元素的name属性的值 + ", key=" + pd.getKey()// .jpdl.xml根元素的key属性的值,如果不写,默认为name属性的值 + ", version=" + pd.getVersion()// 默认自动维护,第1个是1,以后相同key的都会自动加1 + ", deploymentId=" + pd.getDeploymentId()); // 所属的某个Deployment的对象 } }
  • 29. 北京传智播客教育 www.itcast.cn流程定义管理CRUD删除流程定义(使用部署流程定义ID) // 删除(使用流程定义ID) @Test public void testDeleteById() throws Exception { String deploymentId = "90001"; // 删除某部署对象(也可以称之为删除流程流程定义),如果有关联的执行信息,就报错 // processEngine.getRepositoryService().deleteDeployment(deploymentId); // 删除某部署对象(也可以称之为删除流程流程定义),如果有关联的执行信息,就级联删除 processEngine.getRepositoryService().deleteDeploymentCascade( deploymentId); }
  • 30. 北京传智播客教育 www.itcast.cn流程定义管理CRUD查看流程定义的流程图 // 查看流程图(xxx.png) @Test public void testShowProcessImage() throws Exception { // 获取文件内容 String deploymentId = "1"; String resourceName = "helloworld/helloworld.png"; InputStream in = processEngine.getRepositoryService()// .getResourceAsStream(deploymentId, resourceName); // 保存到c:/ FileOutputStream out = new FileOutputStream("c:/process.png"); for (int b = -1; (b = in.read()) != -1;) { out.write(b); } in.close(); out.close(); }
  • 31. 北京传智播客教育 www.itcast.cn流程定义管理CRUD查询所有最新版本的流程定义 @Test public void testFindAllLatestVersions() throws Exception { // 查询,把最大的版本都排到后面 List list = processEngine.getRepositoryService()// .createProcessDefinitionQuery()// .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)// .list(); // 过滤出最新的版本 Map map = new LinkedHashMap(); for (ProcessDefinition pd : list) { map.put(pd.getKey(), pd); } // 显示 for (ProcessDefinition pd : map.values()) { System.out.println("id=" + pd.getId()// 格式:{key}-{version} + ", name=" + pd.getName()// .jpdl.xml根元素的name属性的值 + ", key=" + pd.getKey()// .jpdl.xml根元素的key属性的值,如果不写,默认为name属性的值 + ", version=" + pd.getVersion()// 默认自动维护,第1个是1,以后相同key的都会自动加1 + ", deploymentId" + pd.getDeploymentId()); // 所属的某个Deployment的对象 } }
  • 32. 北京传智播客教育 www.itcast.cn流程定义管理CRUD删除流程定义(删除key相同的所有不同版本的流程定义) // 删除(使用流程定义的key) @Test public void testDeleteByKey() throws Exception { // 1,查询指定key的所有版本的流程定义 List list = processEngine.getRepositoryService()// .createProcessDefinitionQuery()// .processDefinitionKey("helloworld")// .list(); // 2,循环删除 for (ProcessDefinition pd : list) { processEngine.getRepositoryService()// .deleteDeploymentCascade(pd.getDeploymentId()); } }
  • 33. 北京传智播客教育 www.itcast.cn流程定义管理CRUD流程定义中涉及到的JBPM表 Deployment 部署对象 1、一次部署的多个文件的信息。对于不需要的流程可以删除和修改。 2、对应的表: jbpm4_deployment jbpm4_deployprop jpbm4_lob ProcessDefinition 流程定义 解析.jpdl.xml后得到的流程定义规则的信息。
  • 34. 北京传智播客教育 www.itcast.cn第三章:流程实例、任务的执行
  • 35. 北京传智播客教育 www.itcast.cn流程实例的执行流程图
  • 36. 北京传智播客教育 www.itcast.cn流程实例的执行部署流程定义: //部署流程定义 @Test public void testDeployment(){ InputStream in = this.getClass().getClassLoader().getResourceAsStream("test/test.zip"); ZipInputStream zip = new ZipInputStream(in); String processDeploymentId = processEngine.getRepositoryService()// .createDeployment()// .addResourcesFromZipInputStream(zip)// .deploy(); System.out.println(processDeploymentId); }
  • 37. 北京传智播客教育 www.itcast.cn流程实例的执行启动流程实例: // 启动流程实例 @Test public void testStartProcessInstance() throws Exception { ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("流程实例启动成功,processInstanceId=" + pi.getId()); }
  • 38. 北京传智播客教育 www.itcast.cn流程实例的执行查看我的任务列表: @Test public void testFindMyTaskList() throws Exception { // 查询 String userId = "部门经理"; // List list = processEngine.getTaskService().findPersonalTasks(userId); List list = processEngine.getTaskService()// .createTaskQuery()// .assignee(userId)// 要是指定的办理人 // .count() // .page(firstResult, maxResults) .list(); // 显示 for (Task task : list) { System.out.println("id=" + task.getId()// + ", name=" + task.getName()// 任务的名称 + ", assignee=" + task.getAssignee()// 任务的办理人 + ", createTime=" + task.getCreateTime()// 任务的创建时间 + ", executionId=" + task.getExecutionId()); // 所属的执行对象的id } }
  • 39. 北京传智播客教育 www.itcast.cn流程实例的执行办理任务: // 办理任务 @Test public void testCompleteTask() throws Exception { String taskId = "20002"; processEngine.getTaskService().completeTask(taskId); }
  • 40. 北京传智播客教育 www.itcast.cn流程实例的执行流程向后执行一步:(当该流程不做处理的时候使用) // 让流程向后执行一步 @Test public void testSignalExecution() throws Exception { //String executionId = "helloworld.20001"; //String signalName = "to 审批 [总经理]"; String executionId = "helloworld.20001"; processEngine.getExecutionService().signalExecutionById(executionId,"to 审批 [总经理]"); }
  • 41. 北京传智播客教育 www.itcast.cn流程实例的执行流程实例涉及的概念,及涉及到数据库表 Execution 执行对象 按流程定义执行一次的过程信息. 对应的表: jbpm4_execution 正在执行的信息 jbpm4_hist_procinst 已经执行完的历史信息 ProcessInstance 流程实例 特指流程从开始到结束的那个最大的执行分支。 Task 任务 执行到某任务环节时生成的任务信息。 对应的表: jbpm4_task 正在执行的任务信息 jbpm4_hist_task 已经执行完的历史任务信息
  • 42. 北京传智播客教育 www.itcast.cn第四章:流程变量
  • 43. 北京传智播客教育 www.itcast.cn流程变量流程图
  • 44. 北京传智播客教育 www.itcast.cn流程变量设置流程变量: // 设置流程变量 @Test public void testSetVariable() throws Exception { String executionId = "test.80001"; String name = "请假天数"; Object value = new Integer(5); processEngine.getExecutionService().setVariable(executionId, name, value); //Form form = new Form(1L, "张三请假11天"); //processEngine.getExecutionService().setVariable(executionId, "form", form); }注意:Object对象需要实现: implements java.io.Serializable
  • 45. 北京传智播客教育 www.itcast.cn流程变量获取流程变量: // 获取流程变量 @Test public void testGetVariable() throws Exception { String executionId = "test.80001"; String name = "请假天数"; Object value = processEngine.getExecutionService().getVariable(executionId, name); System.out.println(name + " = " + value); //Form form = (Form) processEngine.getExecutionService().getVariable(executionId, "form"); //System.out.println("id=" + form.getId() + ", title=" + form.getTitle()); }
  • 46. 北京传智播客教育 www.itcast.cn流程变量流程变量设置和获取实例场景: { // ExecutionService executionService = processEngine.getExecutionService(); // TaskService taskService = processEngine.getTaskService(); // // ======================================== // // 设置变量的方法 // // 通过Execution设置一个变量 // executionService.setVariable(executionId, name, value); // // 通过Execution设置多个变量 // executionService.setVariables(executionId, variablesMap); // // 通过Task设置多个变量 // taskService.setVariables(taskId, variablesMap); // // 在启动流程实例时,同时也设置一些流程变量 // executionService.startProcessInstanceByKey(processDefinitionKey, variablesMap); // // 在完成任务时,同时也设置一些流程变量 // taskService.completeTask(taskId, variablesMap); // // ======================================== // // 获取变量的方法 // // 通过Execution获取一个变量 // executionService.getVariable(executionId, variableName); // // 通过Execution获取所有变量的名称集合 // executionService.getVariableNames(executionId); // // 通过Execution获取所有变量的信息 // executionService.getVariables(executionId, variableNames); }
  • 47. 北京传智播客教育 www.itcast.cn流程变量流程变量涉及的概念,及涉及到数据库表 流程变量 在流程执行或者任务执行的过程中,用于设置和获取变量,使用流程变量在流程传递的过程中传递业务参数。 对应的表: jbpm4_variable
  • 48. 北京传智播客教育 www.itcast.cn第五章:连线
  • 49. 北京传智播客教育 www.itcast.cn连线流程图:
  • 50. 北京传智播客教育 www.itcast.cn连线对于不需要查看流程图,只需装载流程的配置文件时: public static void main(String[] args) throws UnsupportedEncodingException { URL url = ProcessTest.class.getResource("test.jpdl.xml"); System.out.println(url.getPath()); System.out.println(URLDecoder.decode(url.getPath(), "UTF-8")); }
  • 51. 北京传智播客教育 www.itcast.cn连线部署流程定义和启动流程实例: // 1,部署流程定义 URL url = getClass().getResource("test.jpdl.xml"); processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("流程定义部署成功!"); // 2,启动流程实例 ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("流程实例启动成功!processInstanceId = " + pi.getId());
  • 52. 北京传智播客教育 www.itcast.cn连线查询任务: // 3,查看当前任务 Task task = processEngine.getTaskService()// .createTaskQuery()// 查询本流程实例中目前仅有的一个任务 .processInstanceId(pi.getId())// .uniqueResult(); System.out.println("taskid="+task.getId()); System.out.println("taskname="+task.getName()); System.out.println("taskactivityName="+task.getActivityName()); // processEngine.getTaskService().completeTask(task.getId());
  • 53. 北京传智播客教育 www.itcast.cn连线执行完第一个任务,并使用指定的连线离开: @Test public void testCompleteTask(){ // 4,执行完第1个任务,并使用指定的Transition离开 String taskId = "200001"; String transitionName1 = "to end1"; String transitionName2 = "to 审批 [总经理]"; // 办理完任务,使用指定名称的Transition离开 // processEngine.getTaskService().completeTask(task.getId(), transitionName2); //processEngine.getTaskService().completeTask(taskId, transitionName2); processEngine.getTaskService().completeTask(taskId); System.out.println("任务执行完毕!"); }
  • 54. 北京传智播客教育 www.itcast.cn连线连线特点: 1、一个活动中可以指定一个或多个Transition(Start中只能有一个,End中没有)。 * 开始活动中只能有一个Transition。 * 结束活动中没有Transition。 * 其他活动中有1条或多条Transition 2、如果只有一个,则可以不指定名称(名称是null); 如果有多个,则要分别指定唯一的名称。
  • 55. 北京传智播客教育 www.itcast.cn第六章:活动
  • 56. 北京传智播客教育 www.itcast.cn活动1:开始活动(start) 代表流程的开始边界,一个流程有且只能有一个Start活动。开始活动只能指定一个Transition。在流程实例启动后,会自动的使用这个唯一的Transition离开开始活动,到一下个活动。 2:结束活动(end;end-error;end-cancel) 代表流程的结束边界,可以有多个,也可以没有。如果有多个,则到达任一个结束活动,整个流程就都结束了;如果没有,则到达最后那个没有Transition的活动,流程就结束了。 3:状态活动(state) 功能:等待。 4:任务活动(task) (1):分配任务: (2):assignment=#{String型的变量},使用变量指定任务的办理人 (3):AssignmentHandler,需要在元素中写子元素。 指定的类要实现AssignmentHandler接口 (4)在其中可以使用Assignable.setAssignee(String),分配个人任务。
  • 57. 北京传智播客教育 www.itcast.cn活动(decision)流程图(判断decision):
  • 58. 北京传智播客教育 www.itcast.cn活动(decision)判断(decision)活动: URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); //Integer value = 300; Integer value = 3000; Map variables = new HashMap(); variables.put("报销金额", value); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test",variables); System.out.println("启动流程实例成功!id="+pi.getId()); Task task = processEngine.getTaskService()// .createTaskQuery()// .processInstanceId(pi.getId())// .uniqueResult(); System.out.println("当前任务的ID="+task.getId()); System.out.println("当前任务的名称="+task.getName()); processEngine.getTaskService().completeTask(task.getId()); System.out.println("任务完成!");
  • 59. 北京传智播客教育 www.itcast.cn活动(decision)判断(decision)活动,判断当前操作的是哪个分支: @SuppressWarnings("serial") public class DecisionHandlerImpl implements DecisionHandler { //用来判断当前操作执行哪个分支 @Override public String decide(OpenExecution execution) { int money = (Integer) execution.getVariable("报销金额"); //让总经理审批一下 if(money>1000){ return "to 总经理审批"; } //让流程结束 return "to end1"; } }
  • 60. 北京传智播客教育 www.itcast.cn活动(fork/join)流程图( fork/join ):
  • 61. 北京传智播客教育 www.itcast.cn活动(fork/join)分签/会签( fork/join )活动: @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("启动流程实例成功!id="+pi.getId()); }
  • 62. 北京传智播客教育 www.itcast.cn个人任务(personal)流程图( personal):
  • 63. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法一,指定办理人: @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("启动流程实例成功!id="+pi.getId()); }
  • 64. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法二,指定办理人: @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); Map variables = new HashMap(); //指定班里人的时候,值必须是String类型 variables.put("userID", "李四"); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test",variables); System.out.println("启动流程实例成功!id="+pi.getId()); }
  • 65. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法三,指定办理人: @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("启动流程实例成功!id="+pi.getId()); }
  • 66. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法三,指定办理人: test.jpdl.xml:
  • 67. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法三,指定办理人: @SuppressWarnings("serial") public class AssignmentHandlerImpl implements AssignmentHandler { @Override public void assign(Assignable assignable, OpenExecution execution) throws Exception { String userId = "王五"; //指定个人任务的办理人 assignable.setAssignee(userId); } }
  • 68. 北京传智播客教育 www.itcast.cn个人任务(personal)可以分配个人任务从一个人到另一个人@Test public void testTaskAssign(){ String taskId = "290008"; //分配人 String userId = "赵六"; processEngine.getTaskService().assignTask(taskId, userId); }
  • 69. 北京传智播客教育 www.itcast.cn个人任务(personal)分配个人任务总结个人任务及三种分配方式: 1:在.jpdl.xml中直接写 assignee="张三" 2:在.jpdl.xml中写 assignee=“#{userId}”,变量的值要是String的。 使用流程变量指定办理人 3,使用AssignmentHandler接口,要是类实现该接口,在类中定义: assignable.setAssignee(userId); // 指定个人任务的办理人 使用任务ID和办理人重新指定办理人: processEngine.getTaskService().assignTask(taskId, userId);
  • 70. 北京传智播客教育 www.itcast.cn组任务(group)流程图(group):
  • 71. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法一,指定办理人: @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("启动流程实例成功!id="+pi.getId()); }
  • 72. 北京传智播客教育 www.itcast.cn组任务(group)查询个人任务列表: //查询我的个人任务列表 @Test public void findMyTaskList(){ String userId = “小A"; List list = processEngine.getTaskService()// .createTaskQuery()// .assignee(userId)// .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("assinee="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } }
  • 73. 北京传智播客教育 www.itcast.cn组任务(group)查询组任务列表: //查询组任务列表 @Test public void findGroupTaskList(){ String userId = “小A"; List list = processEngine.getTaskService()// .createTaskQuery()// .candidate(userId)// .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("assinee="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } }
  • 74. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法二,指定办理人: @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); Map variables = new HashMap(); variables.put("userIDs", "大大,小小,中中"); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test",variables); System.out.println("启动流程实例成功!id="+pi.getId()); }
  • 75. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法三,指定办理人: @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("启动流程实例成功!id="+pi.getId()); }
  • 76. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法三,指定办理人: test.jpdl.xml:
  • 77. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法三,指定办理人: AssignmentHandlerImpl: @SuppressWarnings("serial") public class AssignmentHandlerImpl implements AssignmentHandler { @Override public void assign(Assignable assignable, OpenExecution execution) throws Exception { //添加组任务的用户 assignable.addCandidateUser("张无忌"); assignable.addCandidateUser("张三丰"); } }
  • 78. 北京传智播客教育 www.itcast.cn组任务(group)将组任务分配给个人任务: //将组任务分配给个人任务 @Test public void testTakeTask(){ String taskId = "350008"; //个人任务的办理人 String userId = "周芷若"; processEngine.getTaskService().takeTask(taskId, userId); }
  • 79. 北京传智播客教育 www.itcast.cn组任务(group)将个人任务分配给组任务: //分配个人任务到组任务 @Test public void testTaskAssign(){ String taskId = "350008"; processEngine.getTaskService().assignTask(taskId, null); }
  • 80. 北京传智播客教育 www.itcast.cn组任务(group)向组任务中添加人员: @Test public void addUser(){ String taskId = "350008"; String userId = "张翠山"; processEngine.getTaskService().addTaskParticipatingUser(taskId, userId, Participation.CANDIDATE); }
  • 81. 北京传智播客教育 www.itcast.cn组任务(group)分配组任务总结个人任务及三种分配方式: 1:在.jpdl.xml中直接写 assignee=“小A,小B,小C,小D" 2:在.jpdl.xml中写 assignee=“#{userIds}”,变量的值要是String的。 使用流程变量指定办理人 Map variables = new HashMap(); variables.put("userIDs", "大大,小小,中中"); 3,使用AssignmentHandler接口,使用类实现该接口,在类中定义: //添加组任务的用户 assignable.addCandidateUser("张无忌"); assignable.addCandidateUser(“张三丰”); 组任务分配给个人任务: processEngine.getTaskService().takeTask(taskId, userId); 个人任务分配给组任务: processEngine.getTaskService().assignTask(taskId, null); 向组任务添加人员: processEngine.getTaskService().addTaskParticipatingUser(taskId, userId, Participation.CANDIDATE); 组任务对应的表: jbpm4_participation
  • 82. 北京传智播客教育 www.itcast.cn自定义活动(custom)自定义活动流程图:
  • 83. 北京传智播客教育 www.itcast.cn自定义活动(custom)1:在元素中指定class属性为指定的类。 2:这个类要实现ExternalActivityBehaviour接口,其中有两个方法: 1:execute(ActivityExecution),节点的功能代码 2:signal(ActivityExecution, String, Map),在当前节点等待时,外部发信号时的行为 3:在execute()方法中,可以调用以下方法对流程进行控制 (1):ActivityExecution.waitForSignal(),在当前节点等待。 (2):ActivityExecution.takeDefaultTransition(),使用默认的Transition离开,当前节点中定义的第一个为默认的。 (3):ActivityExecution.take(String transitionName),使用指定的Transition离开 (4):ActivityExecution.end(),结束流程实例 4:也可以实现ActivityBehaviour接口,只有一个方法execute(ActivityExecution),这样就不能等待,否则signal时会有类转换异常。
  • 84. 北京传智播客教育 www.itcast.cn自定义活动(custom)自定义活动: @Test public void test() throws Exception { // 1,部署流程定义 URL url = getClass().getResource("test.jpdl.xml"); processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("流程定义部署成功!"); // 2,启动流程实例 ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("流程实例启动成功!processInstanceId = " + pi.getId()); System.out.println("当前所在的活动:" + pi.findActiveActivityNames()); } // 直接向后执行一步 @Test public void testSignal() throws Exception { String executionId = "test.50007"; processEngine.getExecutionService().signalExecutionById(executionId); }
  • 85. 北京传智播客教育 www.itcast.cn自定义活动(custom)自定义活动的方法: // 当执行到当前活动时要执行的方法 // 默认在执行完本方法后就离开本活动 @Override public void execute(ActivityExecution execution) throws Exception { System.out.println("---> ExternalActivityBehaviourImpl.execute()"); System.out.println("已发送通知."); // // 默认行为,使用唯一的Transition离开本活动 // execution.takeDefaultTransition(); // // 使用指定的Transition离开本活动 // execution.take(transitionName); // 执行完后不离开,而是等待,直到外面调用了signalExecutionById(..)才会离开本活动 execution.waitForSignal(); } // 在离开本活动前要执行方法, // 只有在当前活动停留并使用signalExecutionById(..)方法时才会在离开前执行本方法 //(就是在execute(..)中调用了execution.waitForSignal())。 @Override public void signal(ActivityExecution execution, String signalName, Map parameters) throws Exception { System.out.println("---> ExternalActivityBehaviourImpl.signal()"); }implements ExternalActivityBehaviour
  • 86. 北京传智播客教育 www.itcast.cn第七章:事件
  • 87. 北京传智播客教育 www.itcast.cn事件(event)流程图(event):
  • 88. 北京传智播客教育 www.itcast.cn事件(event)(了解知识)1:在根元素中,或在节点元素中,使用元素指定事件,其中event属性代表事件的类型(start和end表示开始和结束)。 2:在中用子元素,指定处理的类,要求指定的类要实现EventListener接口 3:事件类型: (1):元素放在根元素()中,可以指定event为start或end,表示流程的开始与结束。 (2):元素放在节点元素中,可以指定event为start或end,表示节点的进入与离开 (3):在Start节点中只有end事件,在End节点中只有start事件。 (4):在元素中直接写,就是配置事件。(因为在这里只有一个事件,所以不用写on与类型) (5):在元素中还可以配置assign事件,是在分配任务时触发的。
  • 89. 北京传智播客教育 www.itcast.cn事件(event)事件: @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("启动流程实例成功!id="+pi.getId()); } @Test public void testComplete(){ String taskId = "390008"; processEngine.getTaskService().completeTask(taskId); }
  • 90. 北京传智播客教育 www.itcast.cn事件(event)
  • 91. 北京传智播客教育 www.itcast.cn事件(event)@SuppressWarnings("serial") public class EventListenerImpl implements EventListener { @Override public void notify(EventListenerExecution execution) throws Exception { System.out.println(“触发了事件监听,当前活动为:"+execution.getActivity()); } }
  • 92. 北京传智播客教育 www.itcast.cnJBPM工作流结束