工作流及JBPM

工作流及JBPM

一、业务流程示例
流程性运用:在业务规则中,不同的人参与不同的业务环节,最终形成业务结果。

在业务流程中参与的人员叫做参与者(participant);参与者所要完成的事项称之为活动(task也称为任务);每一个任务都需要操作数据。

JBPM是处理流程应用的,可以解决在业务流程中数据的处理以及在不同的参与者进行不同的任务时的协作。



二、工作流(Work Flow)
WFMC(工作流管理联盟),该组织推出了工作流XML(Wf-XML)和XML过程定义语言(XPDL)。
该组织规定:工作流就是工作流程的计算模型,即将工作流程中的工作如何前后组织在一起的逻辑和规则在计算机中以恰当的模型进行表示并对其实施计算。工作流要解决的主要问题是:为实现某个业务目标,在多个参与者之间,利用计算机,按某种预定规则自动传递文档、信息或者任务。简单地说,工作流就是一系列相互衔接、自动进行的业务活动或任务。我们可以将整个业务过程看作是一条河,其中流过的河水就是待审核的表单。
工作流属于计算机支持的协同工作(Computer Supported Cooperative Work,CSCW)的一部分。

三、工作流管理系统(Workflow Management System, WfMS)?
WFMC定义:工作流管理系统是一个软件系统,它完成工作流的定义和管理,并按照在计算机中预先定义好的工作流逻辑推进工作流实例的执行。其产品结构如附图。

工作流及工作流系统主要概念
流程定义:预先定义的业务流转逻辑
流程实例:业务的一次实际流转过程
参与者:任务的执行者
活动(任务):组成流程定义的节点
活动实例:组成流程实例的元素
流转:从一个节点到另一个节点的行为
工作列表:当前需要办理的任务集合
工作流引擎:工作流的核心组件,对流程实例、任务实例以及其状态进行管理

工作流系统核心模型


思考的问题:为什么要持久化?
最主要的原因是需要状态的延续。

工作流系统研究入口点
如何编写流程定义
如何部署流程
如何加载流程
如何启动流程
如何执行任务
如何完成任务

JBPM简介
JBPM,全称是Java Business Process Management(业务流程管理),它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。jBPM在2004年10月18日,发布了2.0版本,并在同一天加入了JBoss,成为了JBoss企业中间件平台的一个组成部分,它的名称也改成JBoss jBPM。
就是它的商务逻辑定义没有采用目前的一些规范,如WfMC,XPDL, BPML, ebXML, BPEL4WS等,而是采用了它自己定义的JBoss jBPM Process definition language (jPdl)。jPdl认为一个商务流程可以被看作是一个UML状态图。jPdl就是详细定义了这个状态图的每个部分,如起始、结束状态,状态之间的转换,过图型化的流程定义,直观地描述业务流程。   
jBPM的另一个特色是它使用Hibernate来管理它的数据库。Hibernate是目前Java领域最好的一种数据存储层解决方案,只要是 Hibernate 支持的数据库, jBPM 也就支持。通过Hibernate,jBPM将数据的管理职能分离出去,自己专注于商务逻辑的处理。
八、JBPM与之对应的一些概念和名词
1. 流程定义(ProcessDefinition)
定义了流程的业务逻辑,包含业务节点和流转。是有向图结构。
<process-definition name="请假">
<start-state name="start">
<transition name="to_state" to="部门经理审批"/>
</start-state>

<task-node name="门经理审批">
<task>
<assignment class=""/>
</task>
<transition to="end" name="to_end"/>
</task-node>

<end-state name="end"/>
</process-definition>

流程实例(ProcessInstance)
执行期间的体现,包含了流程定义被解释后的一些信息,诸如开始时间,结束时间等及其他一些相关信息。


任务(Task)
是ProcessInstance的组成部分,定义了活动具体的内容。


任务实例(TaskInstance)
Task被解释执行时的信息,包括:开始时间,结束时间,参与者id。


参与者(Actor)
问题:参与者规定为用户还是角色?

Token
概念来自Petri网,Petri网是1960年代由卡尔·A·佩特里发明的,适合于描述异步的、并发的计算机系统模型。Petri网既有严格的数学表述方式,也有直观的图形表达方式,既有丰富的系统描述手段和系统行为分析技术,又为计算机科学提供坚实的概念基础。由于Petri网能够表达并发的事件,被认为是自动化理论的一种。研究领域趋向认为Petri网是所有流程定义语言之母。

Petri网元素:
库所(Place)圆形节点;变迁(Transition)方形节点;有向弧(Connection)是库所和变迁之间的有向弧;令牌(Token)是库所中的动态对象,可以从一个库所移动到另一个库所。

Token是一个指针(运行期的概念),代表着一条执行路径,指向当前流程中正在执行的节点。在实例运行期间,Tokens可能是一树形结构。同一时刻,可能存在多个token,但是只有一个rootToken。

JBPM API
流程定义操作
1).发布流程定义:
//JBPM内部通过各种服务进行协作,服务接口从流程引擎中获得
ProcessEngine processEngine = Configuration.
getProcessEngine();

RepositoryService repositoryService
= processEngine.getRepositoryService();

//发布流程定义时会返回一个流程定义的Id
String depolyId = repositoryService.createDeployment().
addResourceFromClasspath("helloWorld.jpdl.xml")
.deploy();

.查看已发布的流程定义:
List<ProcessDefinition> list = repositoryService.
createProcessDefinitionQuery().list();

for(ProcessDefinition pd : list) {
System.out.println(pd.getId());
}

.删除流程定义
repositoryService.deleteDeploymentCascade(deployId);

级联删除的含义:当前流程定义若有流程实例,调用deleteDeployment()会报异常,需要使用deleteDeploymentCascade()方法。
流程控制
1).开始流程
ExecutionService executionService =
processEngine.getExecutionService();

ProcessInstance pi = executionService.
startProcessInstanceByKey("helloWorld");
//判断流程实例是否结束
//在流转到state时候会等待,直到外部触发器执行
System.out.println(pi.isEnded());

//执行等待的流程
pi = executionService.signalExecutionById(pi.getId());
System.out.println(pi.isEnded());

2).强制终止流程
executionService.endProcessInstance(
pi.getId(),"cancel");

3).删除流程实例
executionService.deleteProcessInstanceCascade(
pi.getId());

* JPBM与tomcat6.X冲突问题
原因是项目中WEB-INF\lib中的三个jar包(juel.jar, juel-engine.jar, juel-impl.jar)和tomcat6下lib中jar包(el-api.jar)冲突
解决方法:
将juel.jar, juel-engine.jar, juel-impl.jar这三个包复制到tomcat6下lib中,并删除原来的el-api.jar,切记要把WEB-INF\lib中的juel.jar, juel-engine.jar, juel-impl.jar删除。不然还是要冲突。

示例:
1.通过字符串发布流程
String xml = request.getParameter("xml");
repositoryService.createDeployment().addResourceFromString(
"process.jpdl.xml", xml).deploy();

2.获取最新流程
protected List<ProcessDefinition> getLastProcessDefinition(
HttpServletRequest request,
HttpServletResponse response) {
List<ProcessDefinition> processDefinitions =
repositoryService.createProcessDefinitionQuery().
orderAsc(ProcessDefinitionQuery.PROPERTY_NAME).list();

Map<String, ProcessDefinition> map =
new LinkedHashMap<String, ProcessDefinition>();

for (ProcessDefinition pd : processDefinitions) {
String key = pd.getKey();
ProcessDefinition definition = map.get(key);
if (definition == null ||
(definition.getVersion()) < pd.getVersion()) {
map.put(key, pd);
}
}
return new ArrayList(map.values());
}

3.删除流程定义
String id = request.getParameter("id");

ProcessDefinition pd = repositoryService.
createProcessDefinitionQuery().
processDefinitionId(id).uniqueResult();

repositoryService.deleteDeployment(pd.getDeploymentId());

4.启动流程
String key = request.getParameter("key");
ProcessInstance pi =
executionService.startProcessInstanceByKey(key);

5.查询流程
String pdId = request.getParameter("id");
return executionService.createProcessInstanceQuery()
.processDefinitionId(pdId).list();

6.执行流程实例
String pid = request.getParameter("pid");
executionService.signalExecutionById(pid);

3.控制流程的活动(节点)
1).控制流程的活动
Start(开始)、End(结束)、Decision(决定选流向)、Fork(分支)、Join(汇聚)、Sub-process(子流程)、State(等待状态)、Custom(操作流程)、Task(生成人工任务)

.原子活动(不会影响流向)
Java、Script、Sql、Hql、Mail

组织架构
在流程定义图上Assignment指定candidate-groups

ProcessEngine processEngine = Configuration.getProcessEngine();
IdentityService identityService
= processEngine.getIdentityService();
identityService.createGroup("admin");
//参数的含义:userId,givenName,familyName,email
identityService.createUser("user1", "user1", "user1");
identityService.createUser("user2", "user2", "user2");
identityService.createMembership("user1", "admin");
identityService.createMembership("user2", "admin");

TaskService taskService = processEngine.getTaskService();

//查询当前用户有多少候选任务
List<Task> groupTaskList =
taskService.findGroupTasks("user1");
Task task = groupTaskList.get(0);
taskService.takeTask(task.getId(), "user1");
taskService.completeTask(task.getId());

事件监听
<on event="start">
<event-listener class=
"com.fendou.wangke.ProcessStartListener"/>
</on>
<on event="end">
<event-listener class=
"com.fendou.wangke.ProcessEndListener"/>
</on>

监听器类需要实现EventListener接口

流程图跟踪
将流程定义文件和图打包成ZIP,例如:leave.zip
发布流程定义和流程图
ProcessEngine processEngine = Configuration.getProcessEngine();
RepositoryService repositoryService =
processEngine.getRepositoryService();
ZipInputStream zis = new ZipInputStream(
this.getClass().getResourceAsStream("/leave.zip"));

repositoryService.createDeployment().
addResourcesFromZipInputStream(zis).deploy();

提供生成图片的JSP页面
ProcessEngine processEngine = Configuration.getProcessEngine();

RepositoryService repositoryService =
processEngine.getRepositoryService();

ProcessDefinition processDefinition =
repositoryService.createProcessDefinitionQuery().
processDefinitionId(pid).uniqueResult();

InputStream is = repositoryService.getResourceAsStream(
processDefinition.getDeploymentId(), "leave.png");

byte[] b = new byte[1024];
int len = -1;
while((len = is.read(b,0,1024)) != -1) {
response.getOutputStream().write(b,0,len);
}

<img src="pic.jsp?id="
style="position:absolute;left:0px;top:0px">

动态显示
ExecutionService executionService =
processEngine.getExecutionService();

ProcessInstance processInstance =
executionService.findProcessInstanceById(id);

Set<String> activityName =
processInstance.findActiveActivityNames();

ActivityCoordinates ac = repositoryService.
getActivityCoordinates(processInstance.
getProcessDefinitionId(),
activityName.iterator().next());

<div style="position:absolute; border:3px solid red;
left:<%=ac.getX()%>px;top:<%=ac.getY()%>px;
width:<%=ac.getWidth()%>px;height:<%=ac.getHeight()%>px"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值