六、开发自己的工作流(Hello World)
1. eclipse插件安装
jbpm提供了在eclipse下的一个可视化插件,通过它我们可以方便的定义工作流,打开jbpm-starters-kit-3.1.4/jbpm-designer/jbpm-gpd-feature目录,我们可以看到下面有一个eclipse文件夹,这里我们通过link的方式为eclipse添加该插件。
在{eclipse_home}/link文件夹下新建jbpm-designer.link文件,用记事本打开该文件加入如下一行:
path=D://jbpm-starters-kit-3.1.4//jbpm-designer//jbpm-gpd-feature
后面的路径即为该插件的存放路径,根据个人情况修改。注意,这里的分隔符使用双斜杠
//
。
2.
新建
jbpm
项目
主菜单“文件->新建->项目”,在弹出的对话框里,有“
Process Project
”项,如下图所示:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/3947cadf3b90433c9a82ec64449fc529.jpg)
选上,单击“下一步”,工程起名“
myjbpm
”,点击下一步为此工程指定一个
jbpm location
,如果时第一次运行该插件,系统会提示你设置一个
jbpm location
。这里我们将
location
设置为
D:/jbpm-starters-kit-3.1.4/jbpm.3
。然后就可以单击“完成”了。然后就生成了如下图所示的一个项目结构:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/d39dba84568644dea8ad9ccde5d5eb7d.png)
这个项目和通常
Eclipse
的项目结构有点不同,不过这是一个现在非常流行的项目结构,
src/main/java
存放源文件,
src/test/java
存放相应的
JUnit
单元测试代码,
src/main/jpdl
存放我们定义的工作流文件。
项目创建起了,介绍一下里面的文件吧:
l
MessageActionHandler
,自动生成的一个
ActionHandler
。
l
hibernate.cfg.xml
jBPM
是用
Hibernate
进行工作流的数据存储的,这个就是
Hibernate
的配置文件。后面我们将讲到如何配置这个文件。
l
jbpm.cfg.xml
jbpm
本身的配置文件。现在是空的,它用的是缺省配置,你想知道有哪些配置就去看这个文件
D:/jbpm-starters-kit- 3.1.4/jbpm.3/src/java.jbpm/org/jbpm/default.jbpm.cfg.xml
l
log4j.properties
这个是日志
API
包
log4j
的配置文件,用过
log4j
的都知道。
l
SimpleProcessTest.java
这个是对最重要的流程配置文件的
processdefinition.xml
单元测试代码。
l
gpd.xml
用于生成流程图的定义文件。都是一些方框的坐标和长宽
l
processdefinition.xml
这个是对最重要的流程配置文件,以后写流程要经常和它打交道。
l
processimage.jpg
一个流程图
3.
简单工作流定义
展开
myjbpm
工程,选中
src/main/jpdl
包,单击鼠标右键,
new->other
,如下图:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/fd610e7659444a3cbe186942dab4e8e7.png)
新建一个
Process Definition
,
process
命名为
HelloWorld
,单击
finish
,结果如下图:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/bd62005d070149398bd195d1500e2d5d.png)
右面的窗口为工作流定义的可视化窗口。选中该窗口单击
eclipse
菜单栏
view->show Grid
为该窗口添加网格,方便后面开发。
1)
定义基本流程
分别向编辑区拖入,
start
、
task node
、
end
节点,用
transition
将他们依次连起来,并分别修改
task node
名为
show message
,
end
节点名为
end
,两个
transition
分别命名为
send
和
ok
,得到如下所示结果:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/54ba856c77ff4e8eb3e67fc4f02632b8.png)
2)
定义泳道
(swimlane)
我们为该流程定义一个名为
user
的泳道
(swimlane)
,点击编辑窗口左下角的
swimlanes
按钮,得到添加泳道界面,单击
add
按钮,按照下图配置相关信息,这样我们就将用户
grover
加入到了泳道
user
中:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/c5052d58eadf4134ad4f092551d41e4e.png)
3)
定义节点任务
打开
eclipse
中的
outline
视图,我们可以看到一个名为
HelloWorld
的
process
节点,展开该节点,如下图:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/6d1b32fa6c114f5592ce42f50fc7f426.png)
右击
start
节点,选择
add task
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/c574d67b58fc4a25a92818f4f5d4c28e.png)
我们看到
start
节点下多出了一个名为
task
的
task
节点:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/88717cb0a5044e6fbfb5c88efc601af7.png)
双击该节点,打开节点编辑窗口,将该
task
改名为
input message
,如下:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/d6dee414c34e462ba5c5b95cc25b96b0.png)
选择左边的
controller
我们为该流程定义一个名为
message
的变量,这个变量就是我们后面要传递的信息,照下图配置该变量:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/34efaa301c1342de9e10a0b4dce41e25.png)
点击
ok
,完成
start
节点下的任务定义。
按照以上步骤,我们再为
message show
节点定义一个名为
show message
的任务,这里的变量名也为
message
,但是属性只有
read
,我们通过这个任务读取前面所输入的
message
信息。注意两个任务的变量名要相对应,如下图:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/ad78c96bbe4849ca83fce16416d31e09.png)
下来点击
assignment
菜单,配置该任务的分配方式,如下图所示,将该任务分配给名为
user
的
swimlane
,此
swimlane
包含了
grover
用户。结果如下图:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/b6add095f82e4036a4ab6409b5db59e8.png)
单击
ok
,我们就完成了该流程的任务定义。这里我们看到多出了两个
task
,如图:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/4d2af2f968214178aba1f7f22e64548c.png)
4)
保存流程定义
单击保存按钮,我们保存该流程定义。保存成功后我们可以看到,在流程定义的包中多出了一个名为
processimage.jpg
的图像文件,该文件为我们定义流程的流程图,如下:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/dc9719811aed4266b6e5881d91680a28.png)
点击编辑窗口下的
source
按钮,我们可以查看通过图形编辑界面自动生成的该流程的
xml
定义,即
processdefinition.xml
中的内容。如下:
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
process-definition
xmlns
=
"urn:jbpm.org:jpdl-3.1"
name
=
"HelloWorld"
>
<
swimlane
name
=
"user"
>
<
assignment
expression
=
"user(grover)"
></
assignment
>
</
swimlane
>
<
start-state
name
=
"start"
>
<
task
name
=
"input message"
>
<
controller
>
<
variable
name
=
"message"
access
=
"read,write,required"
></
variable
>
</
controller
>
</
task
>
<
transition
name
=
"send"
to
=
"message show"
></
transition
>
</
start-state
>
<
task-node
name
=
"message show"
>
<
task
name
=
"show message"
swimlane
=
"user"
>
<
controller
>
<
variable
name
=
"message"
access
=
"read"
></
variable
>
</
controller
>
</
task
>
<
transition
name
=
"OK"
to
=
"end"
></
transition
>
</
task-node
>
<
end-state
name
=
"end"
></
end-state
>
</
process-definition
>
对照刚才的流程定义,我们很容易可以看出各个
xml
标签所对应的意义。具体细节我们将在后面介绍。
5)
部署流程定义
首先我们要启动
jboss
服务,待服务启动成功后单击编辑窗口下的
deployment
按钮,按照下图配相应参数,然后点击
test connection
,如果弹出成功窗口,说明服务器连接正常,否则请检查你的参数设置。
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/d10171d24a84475fbe68c55431ee0279.png)
测试连接成功后,我们点击下面的
deploy process archive
按钮,如果得到成功信息,恭喜你,说明我们定义的工作流已经成功的部署到了
jboss
上,如下图:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/03a5bd5caa6047b8acb2e98a1914b2ae.png)
6)
使用工作流
打开
IE
浏览器,在地址栏中输入
http://localhost:8080/jbpm
,以
cookie monster
身份登陆系统。我们看到
Start New Process Execution
里面多了一项
Hello World
,这就是我们刚才部署过的工作流。
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/6de2b4a150774fdfb6aeccc1ad42c981.png)
点击
input message
我们会看到以下画面:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/6326c7ade5104bceaab2984d8a6f6c8b.png)
注意到左面有个一名为
message
的文本框,这个文本框就是我们在流程定义里定义的变量
message
。右面是本流程的流程图,红色的框代表该流程现在运行到哪一步。我们在文本框内输入
Hello!Congratulations!
。然后点击
save and close task
按钮,提交该内容。之后页面跳转,我们会在上面看到这样一行提示信息:
A new task has been assigned to ‘grover’
。说明第一步流程已完成,将下一步任务委派给泳道
user
中的
grover
。我们点击屏幕左上角的
login as another user
。如图所示:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/3893b48210b74138b86f1dca834b6dae.png)
以
grover
身份登陆系统,我们可以看到在
grover
的主界面下的
tasklist
里多出了一项:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/d85715bbeabd464388c71a3c547f1cdd.png)
单击该任务,我们可以看到同样有一个名为
message
的文本框,但是他的内容是不可编辑的,这和我们定义工作流变量时的设置有关,并且里面的内容正是上一步中
cookie monster
用户所输入的内容。我们还可以注意到,右面流程图中标明该流程已经进入第二步。
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/668c6f59023a4e1c9ee0812ad4d75cd8.png)
继续点击
save and close task
按钮,页面跳转,得到信息:
The process has finished
。
并且
tasklist
中刚才的任务项也不存在了。至此,整个工作流程执行完毕。
7)
工作流管理
Jbpm
为我们提供了简单的工作流管理,单击左面菜单栏的
monitoring
进入
monitoring
界面,点击链接
Process Definitions list
,如下:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/9e1a5a97deb6465b9db30cacb32ff436.png)
得到如下界面,这里我们可以看到目前为止所有的工作流定义以及他们所拥有的实例数。通过该图可以得知
Hello World
目前只有一个实例,即我们刚才执行过的那个实例。
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/309ea325ab1d4640a33f5e51d660d923.png)
我们点击实例数
1
,得到
Hello World
下所有的实例列表,如下图:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/f3cd65713e554b0893ed54c5350959fe.png)
我们只初始化过一个实例,因此这里只有一项,
start
和
end
分别表示该实例开始和结束的时间,我们点击前面的
Id
号,查看该实例的详细信息:
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/1be3dc02b3a947ef906cc097655e02c8.png)
其中,
task
列表列出了该实例所有的
task
,其中
name
表示
task
的名字,
actorId
表示由谁执行该
task
,
date
表示该
task
结束的时间。
Variables
列表列出了该
task
中所有的变量及其值。我们在流程定义里只定义了一项变量,因此这里只有
message
,它的值即为刚才输入的内容。我们还可以通过
update
按钮向列表中添加修改变量。
![](https://p-blog.csdn.net/images/p_blog_csdn_net/fndcz/126201fb08ef4a53a071659681ed46c6.png)
下面的图,即为该流程的流程图。红色的框标明此实例已经结束。
至此,一个简单的工作流就完成了,相信大家从中可以大致的了解
jbpm
定义工组流的基本过程,在后面的章节我们将进一步介绍更多的内容。