Activiti工作流的详细介绍
一、了解工作流
1、工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现。
2、工作流管理系统(Workflow Management System, WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流逻辑进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的支撑环境。
3、常见的工作流框架有Activity、JBPM、OSWorkFlow、WorkFlow。本系列使用activiti5.13版本。
4、工作流框架底层需要有数据库提供支持,activiti5.13版本,有23张表。JBPM4.4框架有18张表。JBPM底层使用hibernate操作数据库。Activiti框架底层使用的mybatis操作数据库。
二、Activiti介绍
Activiti5是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。Activiti基于Apache许可的开源BPM平台,创始人Tom Baeyens是JBoss jBPM的项目架构师,它特色是提供了eclipse插件,开发人员可以通过插件直接绘画出业务流程图。
三、下载与目录结构
官网:https://www.activiti.org/ ,没啥用,打开了也没啥东西。直接在GitHub上下载。
GitHub:https://github.com/Activiti/Activiti 这里下载的时activity-dev
目录结构如下:
database :提供了建表语句。
docs:该目录包含了三种文档:javadocs、userguide、xsd。
- javadocs:API文档,包名按照功能模块划分,org.activiti.engine.*。
- userguide:用户手册,包含环境配置、10分钟快速入门以及各个功能模块的使用教程。
- xsd:包含BPMN2.0规范的XSD文件以及Activiti扩展的自定义标签XSD。
libs:开发用的jar包和源码包。
wars:提供了两个例子程序。
安装activiti流程设计器插件
1、eclipse中安装如下:
1.1、获得插件的安装包
1.2、解压安装包,复制到eclipse中的dropins目录中
1.3、重启eclipse,勾选save选项
IDEA 安装Activiti Designer插件---actiBPM
打开IDEA,按ctrl+alt+S,打开Pluging
安装成功后,创建数据库:
初始化表结构
方式1、使用activiti框架提供的建表语句
在database目录下找到相应数据库的建表语句,执行即可。这里我用的是mysql(可以手动执行,也可用工具)
手动执行:
工具的话就不用说了吧
方式2、使用activiti框架的自动建表功能。activiti框架提供了和hibernate类似的自动建表功能。
创建一个java项目,导入jar包,不知道导哪些jar包,可以到war目录解压示例程序。把lib目录中的jar包拷过来即可。当然数据库驱动包时必不可少的。
1、 不使用配置文件(不建议)
@Testpublic void test1(){//1.创建一个流程引擎配置对象ProcessEngineConfiguration configuration= ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();//设置数据源configuration.setJdbcDriver("com.mysql.jdbc.Driver");configuration.setJdbcUrl("jdbc:mysql:///activiti_demo");configuration.setJdbcUsername("root");configuration.setJdbcPassword("123456");//设置自动建表configuration.setDatabaseSchema("true");//创建一个流程引擎对象,在创建流程引擎对象时会自动建表ProcessEngine engine= configuration.buildProcessEngine();}
2、使用配置文件
配置文件可以到示例程序的class目录拷贝 activiti-context.xml,修改里面的内容即可。
配置文件
<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.StandaloneInMemProcessEngineConfiguration"><property name="jdbcDriver" value="com.mysql.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql:///activiti_demo"/><property name="jdbcUsername" value="root" /><property name="jdbcPassword" value="123456" /><property name="databaseSchemaUpdate" value="true"/></bean>
</bean>
java代码
//使用配置文件@Testpublic void test2(){//1.创建一个流程引擎配置对象String resource="activiti-context.xml";String beanName="processEngineConfiguration";ProcessEngineConfiguration configuration= ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(resource,beanName);//创建一个流程引擎对象,在创建流程引擎对象时会自动建表ProcessEngine engine= configuration.buildProcessEngine();}
3、使用配置文件(使用默认配置),要求配置文件名称必须为activiti-context.xml或者activiti.cfg.xml,配置的信息必须为
配置文件如下:
<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.StandaloneInMemProcessEngineConfiguration"><property name="jdbcDriver" value="com.mysql.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql:///activiti_demo"/><property name="jdbcUsername" value="root" /><property name="jdbcPassword" value="123456" /><property name="databaseSchemaUpdate" value="true"/></bean><!--配置工厂,用于创建流程引擎 id必须为processEngine--><bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean"><property name="processEngineConfiguration" ref="processEngineConfiguration" /></bean>
</bean>
java代码
//使用默认配置文件@Testpublic void test3(){ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();}
了解25张表
Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。
- ACT_RE_*: 'RE'表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
- ACT_RU_*: 'RU'表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
- ACT_ID_*: 'ID'表示identity。 这些表包含身份信息,比如用户,组等等。
- ACT_HI_*: 'HI'表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
- ACT_GE_*: 通用数据, 用于不同场景下。
使用框架提供的API完成流程操作
可以在项目中加入log4j,将框架执行的sql输出到控制台,log4j提供的日志级别:Fatal error warn info debug trace
部署流程定义
需要先画好流程图
/*** 部署流程定义(操作数据表:act_re_deployment、act_re_procdef、act_ge_bytearray)*/@Testpublic void test4() {// 获得一个部署构建器对象,用于加载流程定义文件(test1.bpmn,test.png)完成流程定义的部署ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();DeploymentBuilder builder= processEngine.getRepositoryService().createDeployment();// 加载流程定义文件builder.addClasspathResource("process/test1.bpmn");builder.addClasspathResource("process/test1.png");// 部署流程定义Deployment deployment = builder.deploy();System.out.println(deployment.getId());}
查询流程定义列表
@Testpublic void test5() {//流程定义查询对象,用于查询act_re_procdef表ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();//添加查询条件query.processDefinitionKey("bxlc");query.orderByDeploymentId().desc();//分页查询query.listPage(0, 10);List<ProcessDefinition> list = query.list();for (ProcessDefinition item : list) {System.out.print(item.getId());}}
启动流程实例
什么是流程实例?根据一个流程定义具体的一次执行过程就是一个流程实例,一个流程定义对应多个流程实例(一对多关系)
为了演示:在流程图中指定办理人是谁,现在是写死的,表示只能张三能提交请假申请。后面会讲解如何动态指定。
//根据流程定义的Id启动一个流程实例(操作ACT_RU_EXECUTION、ACT_RU_TASK、ACT_HI_PROCINST、ACT_HI_ACTINST、ACT_HI_TASKINST、ACT_RU_IDENTITYLINK、ACT_HI_IDENTITYLINK表)@Testpublic void test6() {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();String processDefinitionId="qjlc:1:104";ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinitionId);System.out.print(processInstance.getId());//201}
查询个人任务列表
@Testpublic void test7() {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();TaskQuery query = processEngine.getTaskService().createTaskQuery();query.taskAssignee("张三");List<Task> list = query.list();for (Task item : list) {System.out.print(item.getId()+"==="+item.getName());//204===提交请假申请}}
办理任务
//办理任务(主要操作ACT_RU_EXECUTION、ACT_RU_TASK表)@Testpublic void test8() {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();processEngine.getTaskService().complete("204");}
办理任务后,流程就走到了下一个节点,再次查询张三个人任务列表就查不到了,此时用李四去查就可以了。
使用Activiti框架的API操作流程
/*** 使用Activiti框架的API操作流程
*/
public class ActivitiAPITest {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();/*** 部署流程定义 方式一:读取单个的流程定义文件 方式二:读取zip压缩文件*/@Testpublic void test1() {DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();// 方式一:读取单个的流程定义文件deploymentBuilder.addClasspathResource("test1.bpmn");deploymentBuilder.addClasspathResource("test1.png"); Deployment deployment = deploymentBuilder.deploy();// 方式二:读取zip压缩文件/*ZipInputStream zipInputStream = new ZipInputStream(this.getClass().getClassLoader().getResourceAsStream("process.zip"));deploymentBuilder.addZipInputStream(zipInputStream);deploymentBuilder.name("请假流程部署");Deployment deployment = deploymentBuilder.deploy();*/}/*** 查询部署列表*/@Testpublic void test2() {// 部署查询对象,查询表act_re_deploymentDeploymentQuery query = processEngine.getRepositoryService().createDeploymentQuery();List<Deployment> list = query.list();for (Deployment deployment : list) {String id = deployment.getId();System.out.println(id);}}/*** 查询流程定义列表*/@Testpublic void test3() {// 流程定义查询对象,查询表act_re_procdefProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();List<ProcessDefinition> list = query.list();for (ProcessDefinition pd : list) {System.out.println(pd.getName() + "" + pd.getId());}}/*** 删除部署信息*/@Testpublic void test4() {String deploymentId = "1001";// processEngine.getRepositoryService().deleteDeployment(deploymentId);processEngine.getRepositoryService().deleteDeployment(deploymentId,true);}/*** 删除流程定义(通过删除部署信息达到删除流程定义的目的)*/@Testpublic void test5() {String deploymentId = "1401";// processEngine.getRepositoryService().deleteDeployment(deploymentId);processEngine.getRepositoryService().deleteDeployment(deploymentId,true);}/*** 查询一次部署对应的流程定义文件名称和对应的输入流(bpmn png)* * @throws Exception*/@Testpublic void test6() throws Exception {String deploymentId = "101";List<String> names = processEngine.getRepositoryService().getDeploymentResourceNames(deploymentId);for (String name : names) {System.out.println(name);InputStream in = processEngine.getRepositoryService().getResourceAsStream(deploymentId, name);// 将文件保存到本地磁盘/** OutputStream out = new FileOutputStream(new File("d:\\" + name));* byte[] b = new byte[1024]; int len = 0; while((len =* in.read(b))!=-1) { out.write(b, 0, len); } out.close();*/FileUtils.copyInputStreamToFile(in, new File("d:\\" + name));in.close();}}/*** 获得png文件的输入流* * @throws Exception*/@Testpublic void test7() throws Exception {String processDefinitionId = "qjlc:9:1204";InputStream pngInputStream = processEngine.getRepositoryService().getProcessDiagram(processDefinitionId);FileUtils.copyInputStreamToFile(pngInputStream, new File("d:\\my.png"));}/*** 启动流程实例 方式一:根据流程定义的id启动 方式二:根据流程定义的key启动(自动选择最新版本的流程定义启动流程实例)*/@Testpublic void test8() {/** String processDefinitionId = "qjlc:9:1204"; ProcessInstance* processInstance =* processEngine.getRuntimeService().startProcessInstanceById* (processDefinitionId ); System.out.println(processInstance.getId());*/String processDefinitionKey = "qjlc";ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey);System.out.println(processInstance.getId());}/*** 查询流程实例列表,查询act_ru_execution表*/@Testpublic void test9(){//流程实例查询对象,查询act_ru_execution表ProcessInstanceQuery query = processEngine.getRuntimeService().createProcessInstanceQuery();query.processDefinitionKey("qjlc");query.orderByProcessInstanceId().desc();query.listPage(0, 2);List<ProcessInstance> list = query.list();for (ProcessInstance pi : list) {System.out.println(pi.getId() + " " + pi.getActivityId());}}/*** 结束流程实例,操作的表act_ru_execution act_ru_task*/@Testpublic void test10(){String processInstanceId = "1601";processEngine.getRuntimeService().deleteProcessInstance(processInstanceId , "我愿意");}/*** 查询任务列表*/@Testpublic void test11(){//任务查询对象,查询act_ru_task表TaskQuery query = processEngine.getTaskService().createTaskQuery();String assignee = "李四";query.taskAssignee(assignee);query.orderByTaskCreateTime().desc();List<Task> list = query.list();for (Task task : list) {System.out.println(task.getId());}}/*** 办理任务*/@Testpublic void test12(){String taskId = "2902";processEngine.getTaskService().complete(taskId);}/*** 直接将流程向下执行一步*/@Testpublic void test13(){String executionId = "2701";//流程实例idprocessEngine.getRuntimeService().signal(executionId);}/*** 查询最新版本的流程定义列表*/@Testpublic void test14(){ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();query.orderByProcessDefinitionVersion().asc();List<ProcessDefinition> list = query.list();Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>();for (ProcessDefinition pd : list) {map.put(pd.getKey(), pd);}ArrayList<ProcessDefinition> lastList = new ArrayList<>(map.values());for (ProcessDefinition processDefinition : lastList) {System.out.println(processDefinition.getName() + " "+ processDefinition.getVersion() );}}
}
Activiti框架提供的Service对象
- RepositoryService----操作静态的资源(流程定义,bpmn、png)
- RuntimeService-----操作流程实例(启动流程实例、查询流程实例、结束流程实例)
- TaskService-----操作任务(查询任务、办理任务)
- HistoryService----操作历史数据
Activiti框架提供的对象(和表有对应关系)
- Deployment-----act_re_deployment
- ProcessDefinition----act_re_procdef
- ProcessInstance-----act_ru_execution
- Task-----act_ru_task
使用网页版流程设计器
1、将activiti-explorer.war复制到tomcat中
2、启动tomcat,访问http://lcoalhost:8080/activiti-explorer
3、使用kermit/kermit登录
4、
Activiti工作流的详细介绍相关推荐
- Activiti工作流的简单介绍
1.概念 工作流(Workflow)就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某种预定义的规则传递文档.信息 或任务的 ...
- 一、activiti工作流(workflow)入门介绍
activiti官方网站(官网通常很卡,不建议看,直接看我教程就行) http://www.activiti.org/ eclipse离线安装activiti插件并下载教程 https://downl ...
- Activiti工作流
目录 Activiti工作流 概念 Activiti7 介绍 activiti.cfg.xml 流程引擎配置类 工作流引擎的创建 默认创建方式 一般创建方式 Activiti表说明 Service服务 ...
- activiti工作流连接mysql_Activiti工作流 安装myeclipse activiti设计插件并生成数据库表...
从零开始学习Activiti工作流,记录下学习过程. 关于工作流的简介没什么好介绍了,只能说是个很有用的东西,数据库中23张表分别有什么用网上也有很详细的介绍,这里也不多加说明.activiti开发中 ...
- activiti工作流引擎入门教程
activiti简介 Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准. Activiti是一种轻量级,可嵌入的BPM引擎,而且 ...
- Activiti工作流开发笔记(二)-在线流程设计的使用说明
在线流程设计 点击 [在线设计] 按钮,会打开 流程在线设计器 ,对流程的设计都将在该设计器上进行. 可以看到流程设计器由四部分组成: ①:基本操作工具栏 ②:节点.任务.事件类型列表 ③:流程设计画 ...
- Activiti工作流+idea2021入门筑基上篇-修身
Activiti工作流 一.我不是韩立,我叫厉飞雨 一.工作流的简单了解 1.介绍:将一组任务组织起来以完成某个事件的过程 :定义了任务的触发顺序和触发条件,每个任务可以由一个或多个 软件系统 完成, ...
- Activiti工作流视频教程-基于Activiti5工作流实战企业协同OA办公系统
Activiti工作流视频教程-基于Activiti5工作流实战企业协同OA办公系统(spring-data-jpa.uur前台组件) 一.Activiti工作流视频教程课程内容简介 在工作流方面,使 ...
- 手把手教你如何玩转Activiti工作流
一:Activiti的介绍 场景:学校 主角:阿毛 , 班主任 ,教务处处长 问题:有一天,阿毛到学校,感觉到身体不舒服,然后想跟班主任请假,然后班主任告诉阿毛说,你想请假,那么就必须要请假 ...
最新文章
- vs2015 企业版、专业版如何破解(秘钥)
- python入门指南许半仙txt-影帝的脑子坏了 第23章
- 哈理工计算机分数线2020,2021哈尔滨理工大学研究生分数线一览表(含2019-2020历年复试)...
- Effective STL 条款30
- @所有人 Flink Forward Asia 2020 向您发出议题征集邀请!
- 连线IBM大数据案例 让大数据接地气
- Android meta作用,Android中meta-data的使用
- 西瓜书+实战+吴恩达机器学习(二二)概率图模型之马尔可夫随机场
- Delphi天气预报查询
- 第二十七节:Java基础面向对象-静态,单例模式,继承详情知识点
- @Resource真的只是按名称来进行依赖注入吗?@Autowired真的只是按照类型来依赖注入吗?
- 计算机考研复试之计算机网络
- python入门汇总
- Git上传项目提示Push rejected: Push to origin/master was rejected解决办法
- 华为u8500刷机、、root
- 阿里云国际版忘记会员名或登录密码,怎么办?
- HDU2066---------Dijkstra算法代码
- Cocos Creator转盘抽奖
- flutter 跑马灯+渐变透明度背景
- 一个专科生的Java学习历程
热门文章
- Android Activity底层启动过程分析
- 设计模式“六原则一法则”
- JUC-如何选择线程数量
- 服务器常用的4大系统优缺点
- 四、Eureka注册中心
- 那些治愈者会再一次感染新冠病毒吗?
- 不同计算机用户的区别是什么意思,计算机工作站是什么意思(专业级后期工作站配置必须搞懂的7个问题)...
- 捕获用户在该页面停留的时长(前端监测)
- vue埋点 记录页面停留时间
- c++11日期和时间工具-(std::chrono::system_clock)