1:什么是工作流?
|--就是将工作的流程通过程序管理起来,以表单审核和任务办理为主体,实现办公自动化!
个人理解:将一些复杂的业务流程,采用JBMP来管理。但JBMP也需要人员去维护!
2:什么是JBPM?
|--业务流程管理
|--通过png图形方式来描述业务流程,自动根据图形流程生成相应的xml文件! *
|--JBPM采用XML结构的流程描述语言JPDL来描述工作流程!*
|--官网:http://www.jboss.org/jbpm/
|--最新版本 JBPM6 测试版已经2013年5月2日 推出
3:JBPM的开发包
|--http://sourceforge.net/projects/jbpm/files/
下载完之后就是一个jbpm-X.X文件
doc --帮助文档
examples --代码示例
install --安装的相关插件
jbpm.jar --核心包
lib --依赖包
src ---源文件
jboss.eula.txt
license.txt
readme.html
4:为eclipse安装gpd插件
4.1:要求:eclipse3.5以上 及对应版本myeclipse (JDK5 以上)
4.2:myeclipse安装
help -- MyEclipse Configuration Center
software -- addsite
浏览jbpm目录\install\src\gpd\jbpm-gpd-site.zip
右击每一项Add to Profile
Apply 8 changes (安装后重启MyEclipse)
4.3:eclipse安装
找到Help --->再找到Install New Sotftware --------->点击Add---------->再占locat
---->找到%HEOM% \install\src\gpd下的jbpm-gpd-site.zip文件
4.4:配置JPDL的Schema提示
找到src下的jpdl-4.4.xsd,找版本最高的!在myeclipse或eclipse中xml中add添加即可!
5:快速入门-----HelloWorld案例
5.1:搭建 JBPM环境
|--添加Jar包
找到jbpm4.4下的lib文件夹,以下几个不要选中:
|---与我们使用的junit4有冲突
junit.jar
|---不要添加,eclipse有自带的
servlet-api.jar
slf4j-api.jar
|---下面两个就不是jar包
gwt-console-jbpm.war
gwt-console-server-jbpm.war
以下两个版本不一致,都是记录日志的,会造成冲突,抛出slf4j异常!
slf4j-jdk14.jar
slf4j-log4j12.jar //找版本一致的!
添加数据库的驱动包
mysql-connector-java.jar
|--添加xml配置文件
jbpm.cfg.xml //核心配置文件
|---其中就映射了jbpm的核心xml文件,都是jbpm.jar下的!
jbpm.hibernate.cfg.xml //连接数据库的文件
数据库方言必须是 org.hibernate.dialect.MySQL5InnoDBDialect ,它继承MySQL5Dialect,增强了一些功能!
|--在hibernate.coreJar下找到 org.hibernate.dialect-------->MySQL5InnoDBDialect.class文件
log4j.properties //日志配置文件
/*
log4j.rootLogger=error, stdout//保留这话????
*/
|--创建流程图
5.2:创建流程图
|--新建 JBPM 4 Proccess Definition 进行jbpm流程定义!
|--使用task及start和end的图标开始定义
|--Assignment属性
个人任务 candidate-users
主任务 assignee
代理人 Expression
注意:
* 必须要先保存了,才能查看生成的xml文件!
* 如果有乱码,只能重新开始!
* 修改了流程图,那么则需从新部署.....到更新!
* 如果定义是个人任务,则查询任务时,则没有办理人
5.3:初始化十八表
|---初始化表
org.hibernate.cfg.Configuration configuration = new org.hibernate.cfg.Configuration();
|---加载jbpm.hibernate.cfg.xml
configuration.configure("jbpm.hibernate.cfg.xml");
SessionFactory sf = configuration.buildSessionFactory();
6:HelloWotld入门
//0:获取引擎对象
ProcessEngine processEngine = new Configuration().setResource("jbpm.cfg.xml").buildProcessEngine();
###################
以上导包时注意,选择import org.jbpm.api.Configuration包
//1:部署流程对象
@Test
public void test_1(){
|---通过引擎对象来 创建部署对象
NewDeployment deployment = processEngine.getRepositoryService().createDeployment();
|---部署指定的流程图
deployment.addResourceFromClasspath("cn/huizhi/test/huizhi.jpdl.xml");
deployment.addResourceFromClasspath("cn/huizhi/test/huizhi.png");
|---完成部署
String deployementID = deployment.deploy();
System.out.println("部署对象ID:"+deployementID);//40001
}
//2:启动流程实例
@Test
public void show_2(){
|---通过引擎对象获取流程对象
ExecutionService executionService = processEngine.getExecutionService();
|---定义流程图的key
String key = "huizhi";
|---返回流程javabean对象,key返回是一个最新的key
ProcessInstance proce = executionService.startProcessInstanceByKey(key);
System.out.println("流程实例ID:"+proce.getId()); //huizhi.50001
System.out.println("流程定义ID:"+proce.getProcessDefinitionId());//huizhi-2
}
//3:查看个人任务
@Test
public void show_3(){
String userId = "小黑龙";
|---通过引擎对象,获取任务管理对象(service)
TaskService taskService = processEngine.getTaskService();
|---查询办理人的个人任务列表
List<Task> taskList = taskService.findGroupTasks(userId);
System.out.println(taskList);
if(taskList!=null && taskList.size()>0){
for(Task task:taskList){
System.out.println("任务ID:"+task.getId());
System.out.println("任务名称:"+task.getName());
System.out.println("任务的办理人:"+task.getAssignee());
System.out.println("任务处在当前的活动名称:"+task.getActivityName());
System.out.println("任务的创建时间:"+task.getCreateTime());
System.out.println("执行对象ID:"+task.getExecutionId());
}
}
}
//4:完成个人任务
@Test
public void show_4(){
|---指定办理人的 任务的ID”
String taskId = "huizhi.140001";
|---通过引擎对象获取管理 任务的service对象
processEngine.getTaskService().completeTask(taskId);
System.out.println("完成当前任务:任务ID是:"+taskId);
}
/**
* 0:获取引擎对象
* |---加载核心文件
* 1:部署流程对象
* |---加载png和xml文件
* 2:启动流程实例
* 通过流程图的key,启动指定 的流程对象!
* key若没有,默认为Name的值!
* 必须要先部署的,才能启动流程图!
* 3:查看个人任务
* 3.1:必须在流程图定义candidate-users
* 3.2:只能查看当前个人任务,示例如下:
* (比如小明------>小王----->小红)
* 部署完之后start就离开了,指向下一个小明,那只能查询他,而不能查看小明后面的人
* 除非小明任务完成,小红才有任务可查看!
* 3.3:使用findGroupTasks查询个人任务!返回是一个javabean集合
* 4:完成个人任务总结
* 4.1:必须要明确办理人的任务ID(从查询个人任务中获取)
* 4.2:其办理人要以流程图的顺序 从上向下的完成!(后面有跳过)
*
*/
7:流程定义的CRUD
//创建流程引擎 的三种方式
@SuppressWarnings("static-access")
@Test
public void test_1(){
|---第一种:使用默认的配置文件(jbpm.cfg.xml)生成Configuration并构建ProcessEngine:
ProcessEngine processend1 = new Configuration().setResource("jbpm.cfg.xml").buildProcessEngine();
|---第二种:使用指定的配置文件(要放到classPath下cn.itcast包下):
/* ProcessEngine processend2 = new Configuration()
.setResource("src/cn/huizhi/hello/jbpm.cfg.xml")
.buildProcessEngine();*/
|---第三种:使用如下代码获取使用默认src下的配置文件、单例的ProcessEngine对象: ---常用
ProcessEngine processend3 = new Configuration().getProcessEngine();
}
//部署流程对象 :怎么在id中给了id,会抛异常?
@Test
public void newDeploy() throws Exception{
|---通过引擎 对象,获取管理流程的service对象
RepositoryService repository = processEngine.getRepositoryService();
|---通过管理流程对象,创建部署对象
NewDeployment createDeployment = repository.createDeployment();
|---部署指定Xxx.xml及Xxx.png流程图 (从类路径下加载资源文件[只加载一次])
createDeployment.addResourceFromClasspath("procedure/task.jpdl.xml");
createDeployment.addResourceFromClasspath("procedure/task.png");
|---部署完成,返回 部署对象ID
String deploy1 = createDeployment.deploy();
System.out.println("部署对象ID:"+deploy1);
System.out.println("********************************************************");
|---部署 资源为.zip的文件
|---通过本类对象,获取类路径, 通过Loader对象,获取指定文件,返回一个流对象
InputStream in = ProcessDefinitionTest.class.getClassLoader().getResourceAsStream("procedure/Desktop.zip");
if(in!=null){
|---把流对象,转为zip流对象
ZipInputStream zip = new ZipInputStream(in);
|---获取部署对象--------一个部署对象只加载 一次资源文件!
NewDeployment createDeployment2 = processEngine.getRepositoryService().createDeployment();
createDeployment2.addResourcesFromZipInputStream(zip);
String deploy2 = createDeployment2.deploy();//完成部署对象
System.out.println("部署对象ID:"+deploy2);
}
}
//启动流程实例对象
@Test
public void procedure(){
|---通过引擎对象,创建流程实例对象
ExecutionService execution = processEngine.getExecutionService();
String key = "task";
|---根据流程图的key(),启动
ProcessInstance process = execution.startProcessInstanceByKey(key);
System.out.println("流程实例ID:"+process.getId());//task.340001
System.out.println("流程定义ID:"+process.getProcessDefinitionId());//task-13
/* 根据ID查询流程实例ID 好象不行????
* ProcessInstance procById = execution.startProcessInstanceById("iD_1");
System.out.println("流程实例ID:"+procById.getId());*/
}
//查看流程定义
@Test
public void findProcessDefinition(){
RepositoryService repository = processEngine.getRepositoryService();//与部署对象和流程定义相关的Service
List<ProcessDefinition> list = repository.createProcessDefinitionQuery()//创建流程定义的查询对象
.deploymentId(deploymentId)//按照部署对象ID查询
.processDefinitionId(processDefinitionId)//指定流程定义的ID查询
.processDefinitionKey(key)//指定流程定义的key查询
.processDefinitionName(name)//指定流程定义的名称查询
.processDefinitionNameLike(name)//指定流程定义的名称模糊查询
.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)//按照流程定义版本的升序排列
.orderDesc(ProcessDefinitionQuery.PROPERTY_DEPLOYMENT_TIMESTAMP)//按照部署流程时间的降序排列
.count()//返回结果集数量
.page(firstResult, maxResults)//分页查询:firstResult:表示当前页从第几条记录开始检索;maxResults:表示当前页最多显示几条记录
.uniqueResult()//返回惟一结果集对象,比如使用流程定义的ID查询
.list();//查询所有的结果集,返回List,比如说按照流程定义的key查询
if(list!=null && list.size()>0){
for(ProcessDefinition pd:list){
System.out.println("流程定义ID:"+pd.getId());//实质上流程定义的key+版本号
System.out.println("流程定义的名称:"+pd.getName());//对应helloworld.jpdl.xml中name的属性值
System.out.println("流程定义的key:"+pd.getKey());//对应helloworld.jpdl.xml中key的属性值,如果key值不填写,默认是name的属性值
System.out.println("流程定义的版本:"+pd.getVersion());//当流程定义的key值一致的情况的下,此时版本号要逐次累加1,版本号默认从1开始
System.out.println("部署对象ID:"+pd.getDeploymentId());
System.out.println("资源图片名称:"+pd.getImageResourceName());
System.out.println("************************************************");
}
}
}
//查看流程图
@Test
public void showIMG() throws Exception{
|---指定 部署对象ID:
String deplo = "360001";
|---指定 资源图片名称
String resourceName = "procedure/task.png";
|---通过引擎对象,创建管理 流程相关的service对象
RepositoryService repository = processEngine.getRepositoryService();
|---获取资源文件 (内部缓冲区)
InputStream in = repository.getResourceAsStream(deplo, resourceName);
|---保存路径
OutputStream out = new FileOutputStream(new File("d:/task.png"));
byte[] by = new byte[1024];
for(int len=0;(len=in.read(by))!=-1;){
out.write(by,0,len);
}
out.close();
in.close();
}
//删除流程定义
@Test
public void deleteProcessDefinition(){
|---指定 部署的ID(也是流程I)
String deplo = "310008";
|---获取管理流程的service对象
RepositoryService repository = processEngine.getRepositoryService();
|---删除
/**
* deleteDeployment:不带级联的删除
* * 如果流程没有启动,此时可以使用deleteDeployment方式进行删除
* * 如果流程已经启动,此时不能使用deleteDeployment方式进行删除,会抛出异常
* */
|---repository.deleteDeployment(deplo);//删除没有启动的流程对象
/**
* deleteDeploymentCascade:带级联的删除
* * 不管流程是否已经启动,都能级联与流程相关的所有操作
* */
|---repository.deleteDeploymentCascade(deplo); //级联删除
}
/**查询所有最新版本的流程定义*/
@Test
public void findAllProcess(){
|---获取管理流程的service对象
RepositoryService repository = processEngine.getRepositoryService();
|---获取流程查询对象
ProcessDefinitionQuery createQuert = repository.createProcessDefinitionQuery();
|---根据版本 降序
createQuert.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION);
|---获取所有流程对象
List<ProcessDefinition> list = createQuert.list();
|---创建一个map集合, 特点:可以去掉重复流程对象(key唯一,value任意)
Map<String,ProcessDefinition> map = new HashMap<String,ProcessDefinition>();
|---遍历结果集
if(list!=null && list.size()>0){
for(ProcessDefinition pd : list){
map.put(pd.getKey(), pd);
}
}
|---遍历map
Collection<ProcessDefinition> values = map.values();
|---通过map的value返回的Collection,创建arrayList对象(包装Collection对象),
List<ProcessDefinition> newProce = new ArrayList<ProcessDefinition>(values);
if(newProce!=null && newProce.size()>0){
for(ProcessDefinition pd:newProce){
System.out.println("流程定义ID:"+pd.getId());//实质上流程定义的key+版本号
System.out.println("流程定义的名称:"+pd.getName());//对应helloworld.jpdl.xml中name的属性值
System.out.println("流程定义的key:"+pd.getKey());//对应helloworld.jpdl.xml中key的属性值,如果key值不填写,默认是name的属性值
System.out.println("流程定义的版本:"+pd.getVersion());//当流程定义的key值一致的情况的下,此时版本号要逐次累加1,版本号默认从1开始
System.out.println("部署对象ID:"+pd.getDeploymentId());
System.out.println("资源图片名称:"+pd.getImageResourceName());
System.out.println("************************************************");
}
}
}
/**根据流程key ,删除该流程所有定义(清空指定流程)*/
@Test
public void deleteProcessDefinitionByKey(){
|---获取管理流程的service对象
RepositoryService repository = processEngine.getRepositoryService();
|---获取流程查询对象
ProcessDefinitionQuery createDefinit = repository.createProcessDefinitionQuery();
|---以流程key作为条件
String key = "huizhi";
createDefinit.processDefinitionKey(key);
|---返回一个list
List<ProcessDefinition> list = createDefinit.list();
if(list!=null && list.size()>0){
for(ProcessDefinition pd : list){
String deploymentId = pd.getDeploymentId();//获取流程ID
|---级联删除
repository.deleteDeploymentCascade(deploymentId);
|---repository.deleteDeployment(deploymentId);
}
}
}
8:认识jbpm的18张表
#与部署流程相关的
SELECT * FROM jbpm4_deployment #部署的流程表
SELECT * FROM jbpm4_deployprop #流程定义表
SELECT * FROM jbpm4_lob #png/xml资源表
#与执行对象和流程实例相关的表
SELECT * FROM jbpm4_execution #正在执行的任务对象
SELECT * FROM jbpm4_participation #流程实例的历史表
SELECT * FROM jbpm4_hist_task #任务的历史表(未/已完成)
SELECT * FROM jbpm4_task #正在执行的任务表
#流程变量表
SELECT * FROM jbpm4_variable #流程变量表,就是定义的key和value
9:几个常用对象
9.1:任务对象
TaskService taskService = processEngine.getTaskService();
//常用方法
查询【指定key】的个人列表
.findPersonalTasks(userId);//查询办理人的个人任务列表
TaskQuery createTaskQuery = taskService.createTaskQuery();//创建一个任务的查询对象
以【办理人】以为条件
.assignee(userId) //指定个人任务的办理人查询任务
.candidate(userId) //指定组任务的办理人查询任务 *****
.activityName(activityName) //指定当前活动名称查询
以【ID】为条件
.executionId(executionId) //指定执行对象ID查询
.processInstanceId(processInstanceId) |---按照流程实例ID查询
.processDefinitionId(processDefinitionId) //按照流程定义的ID查询
以【order】排序
.orderAsc(TaskQuery.PROPERTY_CREATEDATE) //按照任务的创建时间升序排列
.orderDesc(TaskQuery.PROPERTY_ASSIGNEE) //按照任务的办理人的降序排列
【额外】条件
.count()//查询结果集的数量
.uniqueResult()//查询结果的惟一结果
.page(firstResult, maxResults)//分页查询
【完成】个人任务
.completeTask(taskId);//指定任务ID完成任务
.completeTask(taskId, outcome); |---指定任务ID和连线的名称完成任务
/**向后执行一步:让流程跳过当前任务,并向后执行*/
processEngine.getExecutionService()//与执行对象和流程实例相关的Service
processEngine.getExecutionService()//与执行对象和流程实例相关的Service
.signalExecutionById(executionId, signalName);//指定执行对象ID和连线的名称完成任务
向后总结:
* 如果当前流程只有1个任务的时候,此时不需要指定连线的名称
* 如果当前流程有多个任务的时候,此时就需要指定连线的名称
9.2:部署对象和流程定义相关的Service
RepositoryService repositoryService = processEngine.getRepositoryService();
//常用方法
.createDeployment()//创建一个部署对象
.addResourcesFromZipInputStream("zip流对象")//使用zip的输入流部署文件
.addResourceFromClasspath("加载类路径下的xml和png文件");
.deploy();//完成部署
9.3:流程对象
ExecutionService executionService = processEngine.getExecutionService();
//常用方法
.startProcessInstanceByKey(processDefinitionKey);//使用流程定义的key启动流程实例,默认按照最新版本的流程启动!
9.4:流程历史对象
HistoryService historyService = processEngine.getHistoryService();
9.4.1:获取历史对象 的查询对象
|---创建历史任务 查询对象 createHistoryProcessInstanceQuery
HistoryTaskQuery history = historyService.createHistoryTaskQuery();
List<HistoryTask> list1 = history.list();
System.out.println(list1.get(0).getExecutionId());
|---创建历史 流程实例 的 查询对象
HistoryProcessInstanceQuery createProce = historyService.createHistoryProcessInstanceQuery();
List<HistoryProcessInstance> list2 = createProce.list();
System.out.println(list2.get(0).getEndActivityName());
|---创建历史活动 实例 的 查询对象
HistoryActivityInstanceQuery haq = historyService.createHistoryActivityInstanceQuery();
List<HistoryActivityInstance> list3 = haq.list();
System.out.println(list3.get(0).getActivityName());
|---创建历史详细 的 查询对象
HistoryDetailQuery hdq = historyService.createHistoryDetailQuery();
List<HistoryDetail> list = hdq.list();
System.out.println(list);
10:流程变量
/**设置流程变量*/
@Test
public void setVariables(){
ExecutionService executionService = processEngine.getExecutionService();
|---定义执行ID
String executionId = "state.200001";
/**一:使用基本数据类型*/
/**
* 参数一:执行对象ID
* 参数二:流程变量的名称
* 参数三:流程变量的值
*/
executionService.setVariable(executionId, "请假", 3);
/**二:使用javabean对象,设置流程变量*/
Person p = new Person();
p.setId(10L);
p.setName("张三丰");
executionService.setVariable(executionId, "人员信息", p);
/**三:使用hibernate的实体类型,将Person的信息保存到Person的表中*/
org.hibernate.cfg.Configuration configuration = new org.hibernate.cfg.Configuration();
configuration.configure("jbpm.hibernate.cfg.xml");
SessionFactory sf = configuration.buildSessionFactory();
Session s = sf.openSession();
Transaction tr = s.beginTransaction();
Person p = new Person();
p.setName("翠山");
s.save(p);
tr.commit();
s.close();
executionService.setVariable(executionId, "人员信息Hibernate", p);
//注意,需要先在hibernart.xml注册映射Person类型
}
/**获取流程变量*/
@Test
public void getVariables(){
ExecutionService executionService = processEngine.getExecutionService();
|---定义执行ID
String executionId = "state.200001";
/**一:使用基本数据类型*/
/**
* 参数一:执行对象ID
* 参数二:流程变量的名称
* 返回值:流程变量的值
*/
Integer value = (Integer)executionService.getVariable(executionId, "请假");
System.out.println("value:"+value);
/**二:使用javabean对象,获取流程变量*/
Person p = (Person)executionService.getVariable(executionId, "人员信息");
System.out.println(p.getId());
System.out.println(p.getName());
/**三:使用hibernate的实体类型,将Person的信息保存到Person的表中*/
Person p = (Person)executionService.getVariable(executionId, "人员信息Hibernate");
System.out.println(p.getId());
System.out.println(p.getName());
}
/**模拟流程变量的设置和获取*/
public void setAndGetVariables(){
|---执行的Service
ExecutionService executionService = processEngine.getExecutionService();
|---任务的Service
TaskService taskService = processEngine.getTaskService();
/**设置流程变量*/
|---使用执行对象ID,和流程变量的名称,和流程变量的值用来设置流程变量,一次只能设置一个流程变量
executionService.setVariable(executionId, name, value)
|---使用执行对象ID,和Map<String,Object>,String表示流程变量的名称,Object表示流程变量的值,使用Map集合,一次能设置多个流程变量
executionService.setVariables(executionId, variables)
|---使用任务ID,和Map<String,Object>,String表示流程变量的名称,Object表示流程变量的值,使用Map集合,一次能设置多个流程变量
taskService.setVariables(taskId, variables);
|---启动流程实例的时候,同时可以设置流程变量,使用Map<String,Object>,String表示流程变量的名称,Object表示流程变量的值,使用Map集合,一次能设置多个流程变量
executionService.startProcessInstanceByKey(processDefinitionKey, variables)
|---使用任务ID完成任务的时候,同时设置流程变量,使用Map<String,Object>,String表示流程变量的名称,Object表示流程变量的值,使用Map集合,一次能设置多个流程变量
taskService.completeTask(taskId, variables)
/**获取流程变量*/
|---使用执行对象ID和流程变量的名称,获取流程变量的值,一次只能获取一个值
executionService.getVariable(executionId, variableName)
|---使用执行对象ID,获取所有的流程变量的名称,并将流程变量的名称放置到Set<String> variablesName --(1)
executionService.getVariableNames(executionId);
|---使用执行对象ID,和流程变量的名称(Set<String>),获取所有流程变量的值,并放置到Map<String,Object>集合中--(2),(1)和(2)配合使用,一次可以获取多个值
executionService.getVariables(executionId, variableNames)
|---使用任务ID和流程变量的名称,获取流程变量的值,一次只能获取一个值
taskService.getVariable(taskId, variableName)
|---使用任务ID,获取所有的流程变量的名称,并将流程变量的名称放置到Set<String> variablesName --(1)
taskService.getVariableNames(taskId);
|---使用任务ID,和流程变量的名称(Set<String>),获取所有流程变量的值,并放置到Map<String,Object>集合中--(2),(1)和(2)配合使用,一次可以获取多个值
taskService.getVariables(taskId, variableNames)
}
JBPM基础知识
最新推荐文章于 2019-05-09 11:00:55 发布