用了很久的时间找网上的例子,整合了一个比较完整的能够运行的demo,现在分享出来:
一、准备工作,
①开发工具eclipse
②需要的jar包:需要Activiti的所有先关jar包,以及spring的一些jar包,然后还需要导入一些log4j,sl4j的一些jar包,具体的可以运行看一下报什么错,然后倒入即可,这里列举一些:
commons-lang3-3.1.jar
,joda-time-2.1.jar,
jta.jar,mybatis-3.1.0.jar,
mysql-connector-java-5.1.7.jar
③数据库采用mysql数据库
二:配置文件
第一个配置文件:
activiti启动需要启动引擎,二引擎就是读取数据库中的数据,这里需要配置一个Activiti的数据库连接配置文件命名为activiti.cfg.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <!-- Database configurations --> <property name="databaseSchemaUpdate" value="true" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti1" /> <property name="jdbcDriver" value="com.mysql.jdbc.Driver" /> <property name="jdbcUsername" value="root" /> <property name="jdbcPassword" value="root" /> <property name="jobExecutorActivate" value="true" /> </bean> </beans>
这里需要说明几点,其实了解spring的同学就应该知道,这就是一个spring的配置文件,创建了一个bean,并注入一些属性,其中:
属性:databaseSchemaUpdate有几个取值:
flase: 默认值。activiti在启动时,会对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常。
true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建。
create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)。
drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)。
属性:jobExecutorActivate是定时任务,详细的大家可以了解http://weibo.com/kafeituzi
其他的就不用说了,都是数据库连接的必要信息
第二个配置是流程配置文件,也就是bpmn文件,这里命名为Interview.bpmn,具体的内容是一些流程节点以及流程的走向等等,如下:
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="Examples" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd"> <process id="Interview" name="某公司2012年实习生招聘流程"> <documentation>招聘工作流程</documentation> <startEvent id="start" name="实习生招聘启动"/> <userTask id="bishi" name="笔试" activiti:candidateGroups="人力资源部"/> <sequenceFlow id="flow1" name="" sourceRef="start" targetRef="bishi"/> <userTask id="yimian" name="技术一面" activiti:candidateGroups="技术部"/> <sequenceFlow id="flow2" name="" sourceRef="bishi" targetRef="yimian"/> <userTask id="ermian" name="技术二面" activiti:candidateGroups="技术部"/> <sequenceFlow id="flow3" name="" sourceRef="yimian" targetRef="ermian"/> <userTask id="hrmian" name="HR面" activiti:candidateGroups="人力资源部"/> <sequenceFlow id="flow4" name="" sourceRef="ermian" targetRef="hrmian"/> <userTask id="luyong" name="录用,发放Offer" activiti:candidateGroups="人力资源部"/> <sequenceFlow id="flow5" name="" sourceRef="hrmian" targetRef="luyong"/> <endEvent id="end" name="实习生招聘结束"/> <sequenceFlow id="flow6" name="" sourceRef="luyong" targetRef="end"/> </process> </definitions>
三、测试代码:
这里加载引擎有两种方式,你可以使用配置文件,也就是上面的activiti.cfg.xml来加载数据库启动引擎,也可以在代码中直接加载数据库这样就不需要activiti.cfg.xml配置文件了,下面两种方式都列出来
A: 第一种: 需要配置文件
ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml").buildProcessEngine();
B: 第二种:不需配置文件
public void createTable() { // 工作流引擎的全部配置 ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration .createStandaloneProcessEngineConfiguration(); // 链接数据的配置 processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver"); processEngineConfiguration .setJdbcUrl("jdbc:mysql://localhost:3306/activiti1?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8"); processEngineConfiguration.setJdbcUsername("root"); processEngineConfiguration.setJdbcPassword("root"); /* * public static final String DB_SCHEMA_UPDATE_FALSE = "false"; * 不能自动创建表,需要表存在 public static final String DB_SCHEMA_UPDATE_CREATE_DROP * = "create-drop"; 先删除表再创建表 public static final String * DB_SCHEMA_UPDATE_TRUE = "true";如果表不存在,自动创建表 */ //如果表不存在,自动创建表 processEngineConfiguration .setDatabaseSchemaUpdate(processEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); // 工作流的核心对象,ProcessEnginee对象 ProcessEngine processEngine = processEngineConfiguration .buildProcessEngine(); System.out.println(processEngine); }
这两种方式都可以,不过到底哪一个好,相信大家都能看出来吧,接下来就是测试流程的代码了:
不多说贴出来
public void test(){ // 加载配置文件 ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml").buildProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); RuntimeService runtimeService = processEngine.getRuntimeService(); repositoryService.createDeployment().addClasspathResource("Interview.bpmn").deploy(); String processId = runtimeService.startProcessInstanceByKey("Interview").getId(); TaskService taskService = processEngine.getTaskService(); //得到笔试的流程 System.out.println("\n***************笔试流程开始***************"); List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("人力资源部").list(); for (Task task : tasks) { System.out.println("人力资源部的任务:name:"+task.getName()+",id:"+task.getId()); taskService.claim(task.getId(), "张三"); } System.out.println("张三的任务数量:"+taskService.createTaskQuery().taskAssignee("张三").count()); tasks = taskService.createTaskQuery().taskAssignee("张三").list(); for (Task task : tasks) { System.out.println("张三的任务:name:"+task.getName()+",id:"+task.getId()); taskService.complete(task.getId()); } System.out.println("张三的任务数量:"+taskService.createTaskQuery().taskAssignee("张三").count()); System.out.println("***************笔试流程结束***************"); System.out.println("\n***************一面流程开始***************"); tasks = taskService.createTaskQuery().taskCandidateGroup("技术部").list(); for (Task task : tasks) { System.out.println("技术部的任务:name:"+task.getName()+",id:"+task.getId()); taskService.claim(task.getId(), "李四"); } System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count()); for (Task task : tasks) { System.out.println("李四的任务:name:"+task.getName()+",id:"+task.getId()); taskService.complete(task.getId()); } System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count()); System.out.println("***************一面流程结束***************"); System.out.println("\n***************二面流程开始***************"); tasks = taskService.createTaskQuery().taskCandidateGroup("技术部").list(); for (Task task : tasks) { System.out.println("技术部的任务:name:"+task.getName()+",id:"+task.getId()); taskService.claim(task.getId(), "李四"); } System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count()); for (Task task : tasks) { System.out.println("李四的任务:name:"+task.getName()+",id:"+task.getId()); taskService.complete(task.getId()); } System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count()); System.out.println("***************二面流程结束***************"); System.out.println("***************HR面流程开始***************"); tasks = taskService.createTaskQuery().taskCandidateGroup("人力资源部").list(); for (Task task : tasks) { System.out.println("技术部的任务:name:"+task.getName()+",id:"+task.getId()); taskService.claim(task.getId(), "李四"); } System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count()); for (Task task : tasks) { System.out.println("李四的任务:name:"+task.getName()+",id:"+task.getId()); taskService.complete(task.getId()); } System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count()); System.out.println("***************HR面流程结束***************"); System.out.println("\n***************录用流程开始***************"); tasks = taskService.createTaskQuery().taskCandidateGroup("人力资源部").list(); for (Task task : tasks) { System.out.println("技术部的任务:name:"+task.getName()+",id:"+task.getId()); taskService.claim(task.getId(), "李四"); } System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count()); for (Task task : tasks) { System.out.println("李四的任务:name:"+task.getName()+",id:"+task.getId()); taskService.complete(task.getId()); } System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count()); System.out.println("***************录用流程结束***************"); HistoryService historyService = processEngine.getHistoryService(); HistoricProcessInstance historicProcessInstance = historyService .createHistoricProcessInstanceQuery() .processInstanceId(processId).singleResult(); System.out.println("\n流程结束时间:"+historicProcessInstance.getEndTime()); processEngine.close(); }
结束