工作流框架Activiti常用功能初探

Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准,包括支持对象管理组(OMG),面对新技术的机遇,诸如互操作性和云架构,提供技术实现。

BPMN是由BPMI(The Business Process Management Initiative)开发了一套标准叫业务流程建模符号(BPMN - Business Process Modeling Notation)BPMN定义了一个业务流程图(Business Process Diagram),该业务流程图基于一个流程图(flowcharting),该流程图被设计用于创建业务流程操作的图形化模型。而一个业务流程模型(Business Process Model),指一个由的图形对象(graphical objects)组成的网状图,图形对象包括活动(acticities)和用于定义这些活动执行顺序的流程控制器(flow controls)。

以下是对Activiti框架几个常用功能的测试。

环境:mysql,eclipse,jdk1.7,activiti5.13

首先将Activiti相关的JAR包导入到项目中,由于JAR众多,这里就不列举了。主要记录代码部分。

1.在eclipse中安装Activiti插件

Help -> InstallNew Software,在如下Install界面板中,点击Add按钮

然后在Name和Location中分别填入如下内容:

Name: Activiti BPMN 2.0 designer

Location: http://activiti.org/designer/update/

然后一直下一步、下一步安装,根据提示重启eclipse


重启后,再打开菜单Windows->Preferences->Activiti->Save下流程流程图片的生成方式

工作流框架Activiti常用功能初探_第1张图片


2.配置log4j,让其打印出sql语句

在项目根目录下创建log4j.properties文件,在此文件中输入以下配置信息
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:\mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout

3.activiti-context.xml配置activiti

在项目根目录创建 activiti-context.xml文件,在其中配置如下内容
其中的activitiStudy为数据库名,须自己提前创建好。
<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 name="jdbcUrl" value="jdbc:mysql:///activitiStudy?useUnicode=true&characterEncoding=UTF-8"/>
		<property name="jdbcUsername" value="root" />
		<property name="jdbcPassword" value="root" />
		<property name="databaseSchemaUpdate" value="true" />
	</bean>

	<!-- 配置一个流程引擎工厂bean,用于创建流程引擎对象 -->
	<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
		<!-- 通过set方法注入流程引擎配置对象 -->
		<property name="processEngineConfiguration" ref="processEngineConfiguration" />
	</bean>
</beans>

4.画流程图

在项目中,在项目根目录下,点击new->other->选择Activiti下的Activiti Diagram新建一个流程图。
工作流框架Activiti常用功能初探_第2张图片
在其中画如下图示
工作流框架Activiti常用功能初探_第3张图片

并设好相关属性

工作流框架Activiti常用功能初探_第4张图片


5.Activiti测试代码

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.io.FileUtils;
import org.junit.Test;

/**
 * 使用Activiti框架的API操作流程
 * 
 * @author PuHaiyang
 * @createTime 2016年6月28日 下午4:50:39
 * @email [email protected]
 * @function Activiti基本功能测试
 *
 */
public class MyActivitiAPITest {
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

	@Test
	public void deployActiviti() {
		// 如果之前没有创建activiti相关的表,调用它会自动创建,由activiti-context.xml文件内容创建
		DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
		deploymentBuilder.addClasspathResource("MyTest.bpmn");
		deploymentBuilder.addClasspathResource("MyTest.png");
		deploymentBuilder.name("i_am_name");
		Deployment deploy = deploymentBuilder.deploy();
		System.out.println(deploy.getId());
		// 部署信息表 insert into ACT_RE_DEPLOYMENT(ID_, NAME_, CATEGORY_,
		// DEPLOY_TIME_) values(?, ?, ?, ?)
		// 二进制数据表,bpmn文件插入 insert into ACT_GE_BYTEARRAY(ID_, REV_, NAME_,
		// BYTES_, DEPLOYMENT_ID_, GENERATED_) values (?, 1, ?, ?, ?, ?)
		// 二进制数据表,png文件插入 insert into ACT_GE_BYTEARRAY(ID_, REV_, NAME_, BYTES_,
		// DEPLOYMENT_ID_, GENERATED_) values (?, 1, ?, ?, ?, ?)
		// 流程定义数据表 insert into ACT_RE_PROCDEF(ID_, REV_, CATEGORY_, NAME_, KEY_,
		// VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_,
		// DESCRIPTION_, HAS_START_FORM_KEY_, SUSPENSION_STATE_) values (?, 1,
		// ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
	}

	/**
	 * 查询部署列表
	 */
	@Test
	public void queryDeployment() {
		DeploymentQuery deploymentQuery = processEngine.getRepositoryService().createDeploymentQuery();
		List<Deployment> list = deploymentQuery.list();
		for (Deployment deployment : list) {
			String id = deployment.getId();
			System.out.println(id);
		}
	}

	/**
	 * 删除部署信息
	 */
	@Test
	public void deleteDeployment() {
		String deploymentId = "1";
		// 第二个参数代表级联操作
		processEngine.getRepositoryService().deleteDeployment(deploymentId, true);
		// 删除所有相关的activiti信息
	}

	/**
	 * 查询一次部署对应的流程定义文件名称和对应的输入流(bpmn png)
	 * 
	 * @throws Exception
	 */
	@Test
	public void queryDeploymentResource() 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);
			// 将文件保存到本地磁盘
			// FileUtils来自commons-io-xxx.jar
			FileUtils.copyInputStreamToFile(in, new File("d:\\" + name));
			in.close();
		}
	}

	/**
	 * 获得流程表中流程图
	 * 
	 * @throws Exception
	 */
	@Test
	public void getProcessDiagream() throws Exception {
		String processDefinitionId = "myProcess:1:104";
		InputStream pngInputStream = processEngine.getRepositoryService().getProcessDiagram(processDefinitionId);
		FileUtils.copyInputStreamToFile(pngInputStream, new File("d:\\my.png"));
	}

	/**
	 * 启动流程实例 <br>
	 * 方式一:根据流程定义的id启动 <br>
	 * 方式二:根据流程定义的key启动(自动选择最新版本的流程定义启动流程实例)
	 */
	@Test
	public void startProcess() {
		/*
		 * 方式一:根据流程定义的id启动 String processDefinitionId = "myProcess:1:104";
		 * ProcessInstance processInstance =
		 * processEngine.getRuntimeService().startProcessInstanceById
		 * (processDefinitionId ); System.out.println(processInstance.getId());
		 */

		// 方式二:根据流程定义的key启动(自动选择最新版本的流程定义启动流程实例)
		String processDefinitionKey = "myProcess";
		ProcessInstance processInstance = processEngine.getRuntimeService()
				.startProcessInstanceByKey(processDefinitionKey);
		System.out.println(processInstance.getId());
		// 调用SQL语句如下
		// 1 ACT_RU_EXECUTION 运行时流程执行实例表
		// insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_,
		// BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_,
		// IS_SCOPE_,IS_EVENT_SCOPE_, PARENT_ID_, SUPER_EXEC_,
		// SUSPENSION_STATE_, CACHED_ENT_STATE_) values ( ?, 1, ?, ?, ?, ?, ?,
		// ?, ?, ?, ?, ?, ?, ? )

		// 2 ACT_HI_PROCINST 历史流程实例表
		// insert into ACT_HI_PROCINST ( ID_, PROC_INST_ID_, BUSINESS_KEY_,
		// PROC_DEF_ID_, START_TIME_, END_TIME_, DURATION_, START_USER_ID_,
		// START_ACT_ID_, END_ACT_ID_, SUPER_PROCESS_INSTANCE_ID_,
		// DELETE_REASON_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

		// 3 ACT_HI_ACTINST 历史节点表
		// insert into ACT_HI_ACTINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_,
		// EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, ACT_NAME_,
		// ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_ ) values ( ?,
		// ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

		// 4 ACT_HI_ACTINST 历史节点表
		// insert into ACT_HI_ACTINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_,
		// EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, ACT_NAME_,
		// ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_ ) values ( ?,
		// ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

		// 5 ACT_RU_TASK 运行时任务节点表
		// insert into ACT_RU_TASK (ID_, REV_, NAME_, PARENT_TASK_ID_,
		// DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_,
		// DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_,
		// TASK_DEF_KEY_, DUE_DATE_, SUSPENSION_STATE_) values (?, 1, ?, ?, ?,
		// ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

		// 6 ACT_HI_TASKINST 历史任务实例表
		// insert into ACT_HI_TASKINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_,
		// EXECUTION_ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, OWNER_,
		// ASSIGNEE_, START_TIME_, CLAIM_TIME_, END_TIME_, DURATION_,
		// DELETE_REASON_, TASK_DEF_KEY_, FORM_KEY_, PRIORITY_, DUE_DATE_ )
		// values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

		// 7 ACT_RU_IDENTITYLINK 运行时流程人员表,主要存储任务节点与参与者的相关信息
		// insert into ACT_RU_IDENTITYLINK (ID_, REV_, TYPE_, USER_ID_,
		// GROUP_ID_, TASK_ID_, PROC_INST_ID_, PROC_DEF_ID_) values (?, 1, ?, ?,
		// ?, ?, ?, ?)

		// 8 ACT_HI_IDENTITYLINK 历史流程人员表
		// insert into ACT_HI_IDENTITYLINK (ID_, TYPE_, USER_ID_, GROUP_ID_,
		// TASK_ID_, PROC_INST_ID_) values (?, ?, ?, ?, ?, ?)

	}

	/**
	 * 查询流程实例列表,查询act_ru_execution表
	 */
	@Test
	public void queryRuntimeProcess() {
		// 流程实例查询对象,查询act_ru_execution表
		ProcessInstanceQuery query = processEngine.getRuntimeService().createProcessInstanceQuery();
		query.processDefinitionKey("myProcess");
		query.orderByProcessInstanceId().desc();
		query.listPage(0, 2);
		List<ProcessInstance> list = query.list();
		for (ProcessInstance pi : list) {
			System.out.println(pi.getId() + " " + pi.getActivityId());
		}
	}

	/**
	 * 不通过<br>
	 * 删除流程实例
	 */
	@Test
	public void deleteProcess() {
		String processInstanceId = "201";
		processEngine.getRuntimeService().deleteProcessInstance(processInstanceId, "不准逃课!");

		// 执行删除部分SQL如下
		// 1 ACT_RU_TASK 运行时任务节点表
		// delete from ACT_RU_TASK where ID_ = ? and REV_ = ?

		// 2 ACT_RU_IDENTITYLINK 运行时流程人员表,主要存储任务节点与参与者的相关信息
		// delete from ACT_RU_IDENTITYLINK where ID_ = ?

		// 3 ACT_RU_EXECUTION 运行时流程执行实例表
		// delete from ACT_RU_EXECUTION where ID_ = ? and REV_ = ?

		// 执行更新部分SQL如下
		// 1 ACT_HI_PROCINST 历史流程实例表
		// update ACT_HI_PROCINST set PROC_DEF_ID_ = ?, START_TIME_ = ?,
		// END_TIME_ = ?, DURATION_ = ?, END_ACT_ID_ = ?, DELETE_REASON_ = ?
		// where ID_ = ?

		// 2 ACT_HI_ACTINST 历史节点表
		// update ACT_HI_ACTINST set EXECUTION_ID_ = ?, ASSIGNEE_ = ?, END_TIME_
		// = ?, DURATION_ = ? where ID_ = ?

		// 3 ACT_HI_TASKINST 历史任务实例表
		// update ACT_HI_TASKINST set EXECUTION_ID_ = ?, NAME_ = ?,
		// PARENT_TASK_ID_ = ?, DESCRIPTION_ = ?, OWNER_ = ?, ASSIGNEE_ = ?,
		// CLAIM_TIME_ = ?, END_TIME_ = ?, DURATION_ = ?, DELETE_REASON_ = ?,
		// TASK_DEF_KEY_ = ?, FORM_KEY_ = ?, PRIORITY_ = ?, DUE_DATE_ = ? where
		// ID_ = ?
	}

	/**
	 * 查询任务
	 */
	@Test
	public void queryTask() {
		// 任务查询对象,查询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());
		}
		// 执行sql如下
		// 1 ACT_GE_PROPERTY 属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录,
		// select * from ACT_GE_PROPERTY where NAME_ = ?

		// 2 ACT_RU_TASK 运行时任务节点表
		// select distinct RES.* from ACT_RU_TASK RES WHERE RES.ASSIGNEE_ = ?
		// order by RES.CREATE_TIME_ desc LIMIT ? OFFSET ?
	}

	/**
	 * 处理任务
	 */
	@Test
	public void completeTask() {
		String taskId = "304";
		processEngine.getTaskService().complete(taskId);

		// 执行的主要SQL如下
		// 1 ACT_GE_PROPERTY 属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录
		// update ACT_GE_PROPERTY SET REV_ = ?, VALUE_ = ? where NAME_ = ? and
		// REV_ = ?

		// 2 ACT_HI_ACTINST 历史节点表
		// insert into ACT_HI_ACTINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_,
		// EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, ACT_NAME_,
		// ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_ ) values ( ?,
		// ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

		// 3 ACT_RU_TASK 运行时任务节点表
		// insert into ACT_RU_TASK (ID_, REV_, NAME_, PARENT_TASK_ID_,
		// DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_,
		// DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_,
		// TASK_DEF_KEY_, DUE_DATE_, SUSPENSION_STATE_) values (?, 1, ?, ?, ?,
		// ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

		// 4 ACT_HI_TASKINST 历史任务实例表
		// insert into ACT_HI_TASKINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_,
		// EXECUTION_ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, OWNER_,
		// ASSIGNEE_, START_TIME_, CLAIM_TIME_, END_TIME_, DURATION_,
		// DELETE_REASON_, TASK_DEF_KEY_, FORM_KEY_, PRIORITY_, DUE_DATE_ )
		// values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

		// 5 ACT_RU_IDENTITYLINK 运行时流程人员表,主要存储任务节点与参与者的相关信息
		// insert into ACT_RU_IDENTITYLINK (ID_, REV_, TYPE_, USER_ID_,
		// GROUP_ID_, TASK_ID_, PROC_INST_ID_, PROC_DEF_ID_) values (?, 1, ?, ?,
		// ?, ?, ?, ?)

		// 6 ACT_HI_IDENTITYLINK 历史流程人员表
		// insert into ACT_HI_IDENTITYLINK (ID_, TYPE_, USER_ID_, GROUP_ID_,
		// TASK_ID_, PROC_INST_ID_) values (?, ?, ?, ?, ?, ?)

		// 7 ACT_HI_TASKINST 历史任务实例表
		// update ACT_HI_TASKINST set EXECUTION_ID_ = ?, NAME_ = ?,
		// PARENT_TASK_ID_ = ?, DESCRIPTION_ = ?, OWNER_ = ?, ASSIGNEE_ = ?,
		// CLAIM_TIME_ = ?, END_TIME_ = ?, DURATION_ = ?, DELETE_REASON_ = ?,
		// TASK_DEF_KEY_ = ?, FORM_KEY_ = ?, PRIORITY_ = ?, DUE_DATE_ = ? where
		// ID_ = ?

		// 8 ACT_RU_EXECUTION 运行时流程执行实例表
		// update ACT_RU_EXECUTION set REV_ = ?, PROC_DEF_ID_ = ?, ACT_ID_ = ?,
		// IS_ACTIVE_ = ?, IS_CONCURRENT_ = ?, IS_SCOPE_ = ?, IS_EVENT_SCOPE_ =
		// ?, PARENT_ID_ = ?, SUPER_EXEC_ = ?, SUSPENSION_STATE_ = ?,
		// CACHED_ENT_STATE_ = ? where ID_ = ? and REV_ = ?

		// 9 ACT_HI_ACTINST 历史节点表
		// update ACT_HI_ACTINST set EXECUTION_ID_ = ?, ASSIGNEE_ = ?, END_TIME_
		// = ?, DURATION_ = ? where ID_ = ?

		// 10 ACT_RU_TASK 运行时任务节点表
		// delete from ACT_RU_TASK where ID_ = ? and REV_ = ?

	}

	/**
	 * 直接将流程向下执行一步
	 */
	@Test
	public void signal() {
		String executionId = "301";// 流程实例id
		processEngine.getRuntimeService().signal(executionId);
	}

	/**
	 * 查询最新版本的流程定义列表
	 */
	@Test
	public void getLastTasks() {
		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());
		}
	}
}



你可能感兴趣的:(log4j,工作流,Activiti,Activiti,Activiti,数据库分析,activiti常用功能)