标签:
内容:
1、工作流概念
2、安装eclipse插件(工作流流程设计器插件)
3、创建activiti框架提供的数据库表结构(23张表)
4、学习工作流框架API,操作流程
工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。(按照某种预定义的规则来执行流程)
工作流管理系统(Workflow Management System,WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流逻辑进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的支撑环境。
常见的工作流框架:JBPM4.4、activiti5.13、OSWorkFlow
JDK1.6或者更高版本
解压压缩文件到eclipse的dropins目录中
activiti-eclipse-plugin.zip
重启eclipse,勾选save选项(自动生成流程图)
安装成功后new->Other…打开面板后可以看到activiti即安装成功
activiti目录结构:
database:数据库建/删/更新表sql
docs:java文档,用户向导,约束xsd
libs:jar包
wars:案例
activiti框架底层有一套数据库表提供支持,activiti5.13版本对应23张表,JBPM4.4对应18张表。工作流框架底层使用持久化技术和数据库交互,activiti框架底层使用mybatis操作数据库,JBPM底层使用hibernate操作数据库。
3.1 执行框架提供的sql文件建表(建议)
创建sql文件位置activiti-5.13\database\create里
执行命令:
source 把sql文件拖进来
3.2 使用框架提供的自动建表功能建表
jar包:
*在activiti-5.16.1->wars目录下是一些示例项目,解压activiti-rest项目,导入activiti-rest目录中WEB-INF\lib下所有包。添加到classpath中
*手动导入数据库驱动包例如mysql-connector-java.jar
--eclipse如何手动创建library
--右键随意library(比如JRE)→bulid path→configureulid path→libraries →add library →user library→user libraries →new →命名 →add jar →去工作空间的项目lib找到jar ,
创建完成 删除显示在外面的奶瓶即可
使用默认的配置文件:
activiti-rest\WEB-INF\classes下有:
activiti-context.xml : 一个类似spring结构的配置文件,清空内容后改名为activiti.cfg.xml,用来做流程引擎的相关配置
文件中bean的ID规定好的
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!-- 配置流程引擎配置对象 --> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <!-- 注入数据源信息 --> <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///activiti_day1"></property> <property name="jdbcUsername" value="root" ></property> <property name="jdbcPassword" value="root"></property> <!-- 注入自动建表设置 --> <property name="databaseSchemaUpdate" value="true"></property> </bean> <!-- 提供工厂bean,创建流程引擎对象 --> <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean"> <property name="processEngineConfiguration" ref="processEngineConfiguration"></property> </bean> </beans>
执行java代码:
调用ProcessEngines的getDefaultProceeEngine方法时会自动加载classpath下名为activiti.cfg.xml文件
流程引擎对象创建成功运行后数据库会自动建表
// 使用activiti框架提供的自动建表方式创建23张表 @Test public void test3() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); }
Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。用途也和服务的API对应。
1) ACT_RE_*:‘RE‘表示repository。 这个前缀的表包含了流程定义和流程静态资源(图片,规则,等等)。
2) ACT_RU_*:‘RU‘表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
3) ACT_ID_*:‘ID‘表示identity。 这些表包含身份信息,比如用户,组等等。
4) ACT_HI_*:‘HI‘表示history。 这些表包含历史数据,比如历史流程实例,变量,任务等等。
5) ACT_GE_*: general 通用数据, 用于不同场景下。
.1资源库流程规则表
1) act_re_deployment 部署信息表
2) act_re_model 流程设计模型部署表
3) act_re_procdef 流程定义数据表
.2运行时数据库表
1) act_ru_execution 运行时流程执行实例表
2) act_ru_identitylink 运行时流程人员表,主要存储任务节点与参与者的相关信息
3) act_ru_task 运行时任务节点表
4) act_ru_variable 运行时流程变量数据表
.3历史数据库表
1) act_hi_actinst 历史节点表
2) act_hi_attachment 历史附件表
3) act_hi_comment 历史意见表
4) act_hi_identitylink 历史流程人员表
5) act_hi_detail 历史详情表,提供历史变量的查询
6) act_hi_procinst 历史流程实例表
7) act_hi_taskinst 历史任务实例表
8) act_hi_varinst 历史变量表
.4组织机构表
1) act_id_group 用户组信息表
2) act_id_info 用户扩展信息表
3) act_id_membership 用户与用户组对应信息表
4) act_id_user 用户信息表
这四张表很常见,基本的组织机构管理,关于用户认证方面建议还是自己开发一套,组件自带的功能太简单,使用中有很多需求难以满足
.5通用数据表
1) act_ge_bytearray 二进制数据表
2) act_ge_property 属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录,
业务流程建模与标注(Business Process Model andNotation,BPMN) ,描述流程的基本符号,包括这些图元如何组合成一个业务流程图(BusinessProcess Diagram)
使用插件设计一个流程图
说明:流程定义文档有两部分组成:
1) bpmn文件
流程规则文件。在部署后,每次系统启动时都会被解析,把内容封装成流程定义放入项目缓存中。Activiti框架结合这个xml文件自动管理流程。
2) 展示流程图的图片
在系统里需要展示流程的进展图片
6.1ProcessEngine
说明:
1) 在Activiti中最核心的类,其他的类都是由他而来。
2) 产生方式:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
3) 可以产生RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
4) 可以产生RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
5) 可以产生TaskService
TaskService taskService = processEngine.getTaskService();
各个Service的作用:
RepositoryService | 管理流程定义 |
RuntimeService | 执行管理,包括启动、推进、删除流程实例等操作 |
TaskService | 任务管理 |
HistoryService | 历史管理(执行完的数据的管理) |
IdentityService | 组织机构管理 |
FormService | 一个可选服务,任务表单管理 |
ManagerService |
6.2RepositoryService
是Activiti的仓库服务类。所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片。
1) 可以产生DeploymentBuilder,用来定义流程部署的相关参数
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
2) 删除流程定义
repositoryService.deleteDeployment(deploymentId);
6.3RuntimeService
是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息。
6.4TaskService
是activiti的任务服务类。可以从这个类中获取任务的信息。
6.5ProcessDefinition
流程定义类。可以从这里获得资源文件等。
6.6ProcessInstance
代表流程定义的执行实例。如范冰冰请了一天的假,她就必须发出一个流程实例的申请。一个流程实例包括了所有的运行节点。我们可以利用这个对象来了解当前流程实例的进度等信息。
从源代码中可以看出ProcessInstance继承自Execution。但在现实意义上有所区别:
在单线流程中,ProcessInstance与Execution是一致的。
并发执行时, 总线路代表ProcessInstance,而分线路中每个活动代表Execution。
6.7Execution
Activiti用这个对象去描述流程执行的每一个节点。在没有并发的情况下,同ProcessInstance。
查询对象
DeploymentQuery:查询部署表act_re_deployment
ProcessDefinitionQuery:查询流程定义表act_re_procdef
ProcessInstanceQuery:查询流程实例表act_ru_execution
TaskQuery:查询任务表act_ru_task
几个和表对应的对象(接口)
Deployment:对应查询部署表act_re_deployment
ProcessDefinition:对应流程定义表act_re_procdef
ProcessInstance:对应流程实例表act_ru_execution
Task:对应任务表act_ru_task
7.1 部署流程定义操作
public class ActivitiAPITest { ProcessEngine pe = ProcessEngines.getDefaultProcessEngine(); /** * 部署流程定义---- 将设计的流程图插入到数据库 * 部署流程定义 方式一:加载单个的流程定义文件 方式二:加载zip压缩文件 * 操作数据表:act_re_deployment(部署表)、act_re_procdef(流程定义表)、act_ge_bytearray(二进制表) * @throws Exception */ @Test public void test1() throws Exception { DeploymentBuilder deploymentBuilder = pe.getRepositoryService() .createDeployment(); // 方式一:加载单个的流程定义文件 // deploymentBuilder.addClasspathResource("test1.bpmn"); // deploymentBuilder.addClasspathResource("test1.png"); // Deployment deployment = deploymentBuilder.deploy(); // 方式二:加载zip压缩文件 ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream( new File("d:\\process2.zip"))); /* * ZipInputStream zipInputStream = new ZipInputStream(this.getClass() * .getClassLoader().getResourceAsStream("process.zip")); */ deploymentBuilder.addZipInputStream(zipInputStream); deploymentBuilder.name("部署测试"); //返回部署对象 Deployment deployment = deploymentBuilder.deploy(); String id = deployment.getId(); } /** * 查询部署信息数据,查询act_re_deployment */ @Test public void test2() { // pe.getRepositoryService().createDeploymentQuery().list();//查询部署信息数据,查询act_re_deployment // pe.getRepositoryService().createProcessDefinitionQuery().list();//查询流程定义数据 // pe.getRuntimeService().createProcessInstanceQuery().list(); // pe.getTaskService().createTaskQuery().list(); // pe.getHistoryService().createHistoricActivityInstanceQuery().list(); List<Deployment> list = pe.getRepositoryService() .createDeploymentQuery().list(); for (Deployment deployment : list) { System.out.println(deployment.getId() + " " + deployment.getDeploymentTime()); } } /** * 删除部署信息 */ @Test public void test3() { String deploymentId = "401";// 部署ID pe.getRepositoryService().deleteDeployment(deploymentId); boolean cascade = true;// 是否级联删除 pe.getRepositoryService().deleteDeployment(deploymentId, cascade); }
7.2 流程定义操作
/** * 查询流程定义数据 */ @Test public void test4() { // 流程定义查询对象,操作的数据表act_re_procdef ProcessDefinitionQuery query = pe.getRepositoryService().createProcessDefinitionQuery(); // 添加过滤条件 query.processDefinitionNameLike("请假流程"); // 添加排序条件 query.orderByProcessDefinitionVersion().desc(); List<ProcessDefinition> list = query.list(); for (ProcessDefinition pd : list) { System.out.println(pd.getId() + " " + pd.getKey() + " " + pd.getName() + " " + pd.getVersion()); } } /** * 删除流程定义数据,通过删除部署信息达到删除流程定义的目的 */ @Test public void test5() { String deploymentId = "301"; pe.getRepositoryService().deleteDeployment(deploymentId); } /** * 查询最新版本的流程定义数据 */ @Test public void test6() { List<ProcessDefinition> list = pe.getRepositoryService() .createProcessDefinitionQuery().latestVersion().list(); for (ProcessDefinition processDefinition : list) { System.out.println(processDefinition.getId() + " " + processDefinition.getKey() + " " + processDefinition.getVersion()); } } /** * JBPM查询最新版本的流程定义数据 */ @Test public void test7() { ProcessDefinitionQuery query = pe.getRepositoryService() .createProcessDefinitionQuery(); // 按照version升序 query.orderByProcessDefinitionVersion().asc(); List<ProcessDefinition> list = query.list(); Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>(); for (ProcessDefinition processDefinition : list) { map.put(processDefinition.getKey(), processDefinition); } System.out.println(map); list = new ArrayList<>(map.values()); for (ProcessDefinition processDefinition : list) { System.out.println(processDefinition.getId() + " " + processDefinition.getName() + " " + processDefinition.getVersion()); } } /** * 查询一次部署对应的流程定义文件名称和输入流 * * @throws Exception */ @Test public void test8() throws Exception { String deploymentId = "1401";// 部署ID List<String> names = pe.getRepositoryService() .getDeploymentResourceNames(deploymentId); for (String name : names) { System.out.println(name); InputStream in = pe.getRepositoryService().getResourceAsStream(deploymentId, name); FileUtils.copyInputStreamToFile(in, new File("d:\\" + name)); in.close(); /* * byte[] b = new byte[1024]; in.read(b); OutputStream out = new * FileOutputStream(new File("d:\\" + name)); out.write(b); * * out.close(); */ } } /** * 获得png图片文件的输入流 * * @throws Exception */ @Test public void test9() throws Exception { String processDefinitionId = "qjlc:2:104";// 流程定义ID InputStream pngStream = pe.getRepositoryService().getProcessDiagram(processDefinitionId); FileUtils.copyInputStreamToFile(pngStream, new File("d:\\my.png")); pngStream.close(); }
7.3 流程实例操作
什么是流程实例??根据某个流程定义的一次具体的执行过程就是一个流程实例。流程定义和流程实例一对多关系。一个流程实例对应多个任务。
/** * 启动流程实例 方式一:根据流程定义的ID启动流程实例 方式二:根据流程定义的key启动流程实例(建议使用) * 操作的数据表:act_ru_execution(流程实例表)、act_ru_task(任务表) */ @Test public void test10() { String processDefinitionId = "qjlc:7:1004";// 流程定义ID // 方式一:根据流程定义的ID启动流程实例 // ProcessInstance pi = // pe.getRuntimeService().startProcessInstanceById(processDefinitionId); // System.out.println(pi.getId()); String processDefinitionKey = "qjlc";// 流程定义的key // 方式二:根据流程定义的key启动流程实例(建议使用,会自动选择最新版本) ProcessInstance pi = pe.getRuntimeService().startProcessInstanceByKey(processDefinitionKey); System.out.println(pi.getId()); } /** * 查询流程实例 */ @Test public void test11() { // 流程实例查询对象,查询表act_ru_execution ProcessInstanceQuery query = pe.getRuntimeService() .createProcessInstanceQuery(); List<ProcessInstance> list = query.list(); for (ProcessInstance processInstance : list) { System.out.println(processInstance.getId() + " " + processInstance.getActivityId() + " " + processInstance.getProcessDefinitionId()); } } /** * 删除流程实例 */ @Test public void test12(){ String processInstanceId = "1601";//流程实例ID String deleteReason = "不请假了";//删除原因 pe.getRuntimeService().deleteProcessInstance(processInstanceId, deleteReason); }
7.4 查询个人任务
/** * 查询个人任务 * 操作的数据表:act_ru_task */ @Test public void test13(){ //任务查询对象,查询任务表 TaskQuery query = pe.getTaskService().createTaskQuery(); String assignee = "王五"; //添加过滤条件,根据任务的办理人过滤 query.taskAssignee(assignee); List<Task> list = query.list(); for (Task task : list) { System.out.println(task.getId() + " " + task.getName()); } }
7.5 办理任务
/** * 办理个人任务 * 操作数据表:act_ru_task、act_ru_execution */ @Test public void test14(){ String taskId = "1902"; pe.getTaskService().complete(taskId ); }
框架 day55 BOS项目练习(工作流,activiti入门)
标签:
原文地址:http://blog.csdn.net/opopopwqwqwq/article/details/51694646