OSWorkflow
基本概念
>>
http://www.blogdriver.com/showBlog.do?diaryID=113138
| ||
|
电子政务
/ OA
如果要使用
workflow engine
的话
, shark, jbpm
之类的
workflow engine
有点杀鸡用牛刀的味道
. shark
和
jbpm
都强迫你使用它的用户模型
,
怎样把企业现有的用户模型
(
包括组织结构
)
映射过来是很繁琐的事情
,
比如常见的
OA
应用中
,
申请者对应的部门负责人为下一个流程的人工参与者
,
使用
shark
或者
jbpm
都得绕一圈
,
通过现有的人力资源系统
,
获得用户
,
再对应过来
.
这还仅仅是一个简单的需求
,
更不用说国内企业千奇百怪的组织结构
,
以及各种特殊流程
,
用
wfmc
或者其他所谓的
workflow
通用标准去做不怎么标准的事情
,
吃力不讨好
.
用
osworkflow
这种基于状态机的
workflow engine
反而会轻松很多
,
而且它也没有强迫你使用它的用户模型
.
另外纠正一点
: osworkflow
不仅仅支持简单的
BeanShell
,
还支持
java class, bsf, ejb.
如果做电子政务
/ OA
的话
,
觉得目前
osworkflow
是最适用的
opensource
workflow engine.
OSWorkflow
中
BeanShell
的运行环境
>>
http://www.blogdriver.com/showBlog.do?diaryID=109107
| ||
|
/
OSWorkflow
真灵活
>>
http://www.blogdriver.com/showBlog.do?diaryID=108339
| ||
|
跟
OSWorkflow
奋斗一天
>>
http://www.blogdriver.com/showBlog.do?diaryID=107566
| ||
|
OSWorkFlow又爱又恨
http://www.blogdriver.com/showBlog.do?diaryID=182514
OSWorkFlow
我研究已有一段时间了,并已在一些项目中开始使用了。
OSWorkFlow
流程定义灵活清晰,工作流引擎支持多种持久方式(
MemoryStore
,SerializableStore, JDBCStore, OfbizStore, and EJBStore,HibernateStore
等),具有极强的可扩展性。
OSWorkFlow
强大的脚本支持(
BeanShell
、
BSF
等),多样化的
function,function
可以直接使用普通
java
类函数、
Xwork
的
Action
、
JMS
、
EJB
、脚本等。使用
propertyset
动态存取类型化的数据,使用成熟的
Quartz
实现工作流任务定时调度。最新版本
OSWorkFlow2.7
也添加了
Spring
框架的支持,设计器也有了很好的改善。
可是,
OSWorkFlow
的学习资料太少,只有
opensymphony
的一些概论介绍和简单的例子,连一个完善的实际项目使用都没有。代码的注释也是非常少,更不能接受的是只有部分的单元测试,若想在其基础上改进也困难,哎!设计器的代码更烂,好在
OSWorkFlow2.7
的设计器(
Designer2.7
)的改进,总算是能在实际中使用。
OSWorkFlow概论:function(函数)
http://www.blogdriver.com/showBlog.do?diaryID=158730
function
(函数),在
OSWorkFlow
中是用来定义(引用)并执行外部的商业逻辑和服务,实现
OSWorkFlow
与外部具体的应用之间交互。
function
有二种类型:
pre function( 预处理函数 ) 和 post function (后处理函数)
pre function 在工作流的一个转变操作执行之前调用,例如:在执行 Action 的一个结果之前,设置这个结果将导致状态改变的 Owner
<action id="0" name=" 启动工作流 ">
<results>
<unconditional-result id="2" old-status="Finished" status="Queued" step="1" owner="${caller}">
<pre-functions>
<function name="set.caller" type="class">
<arg name="class.name">com.opensymphony.workflow.util.Caller</arg>
</function>
</pre-functions>
</unconditional-result>
</results>
</action>
pre function( 预处理函数 ) 和 post function (后处理函数)
pre function 在工作流的一个转变操作执行之前调用,例如:在执行 Action 的一个结果之前,设置这个结果将导致状态改变的 Owner
<action id="0" name=" 启动工作流 ">
<results>
<unconditional-result id="2" old-status="Finished" status="Queued" step="1" owner="${caller}">
<pre-functions>
<function name="set.caller" type="class">
<arg name="class.name">com.opensymphony.workflow.util.Caller</arg>
</function>
</pre-functions>
</unconditional-result>
</results>
</action>
post function
在工作流的一个转变操作执行完之后调用
:
例如在设备申请工作流中,部门经理审核步骤完成之后可以给申请的员工发
email
通知
等。
function 将被应用在 step 、 Action 、 Result 中
具体见 workflow_2_7.dtd :
..
<!ELEMENT step (meta*, pre-functions?, external-permissions?, actions?, post-functions?)>
<!ELEMENT action (meta*, restrict-to? , validators?, pre-functions?, results, post-functions?)>
<!ELEMENT result (conditions, validators?, pre-functions?, post-functions?)>
..
function
在
action
级别的应用:在执行某一步骤的的
Action
时,它会首先执行当前
Action
级别的
pre-function
,再去寻找
Action
里的
result
。
result
执行完成之后再调用
Action
级别的
post-function
,于是
Action
的执行结束。
如下图:
function 在 result 级别的应用 : 类似 action 级别
function 在 step 级别的应用 : 上一个步骤执行结束,运转到当前步骤,执行当前步骤的 pre-function 。当前步骤执行完成,在未运转到下一步骤
之前,执行
post-function
如下图:
注意:
OSWorkFlow
里的
Action
和我们具体业务操作中的
Action
(比如:
xwork
中的
Action
)的区别
:
OSWorkFlow
的
Action
是个更粗粒度的操作,它是指
OSWorkFlow
某一步骤可以执行的操作。在我们经常用的
action
(比如:
xwork
中的
Action
),是业务相关的一个操作,在
OSWorkFlow
相当于一个具体的
function
。
opensymphony
的开源项目
>>
| |||
|
BeanShell
的中文问题
>>
http://www.blogdriver.com/showBlog.do?diaryID=108228
| ||
|
OsWorkFlow配合Hibernate攻略>>
http://www.blogdriver.com/showBlog.do?diaryID=178570
1.
下载最新的
OsWorkflow2.7.0,
地址是
https://osworkflow.dev.java.net/files/documents/635/4647/osworkflow-2.7.0.zip
2.
解压后
,
把
osworkflow-2.7.0-example.war
解压到一个目录,我一般起
web
,方便对里面进行修改
3.
部署到
Tomcat5
4.
试验一下
,
这个时候
,
默认的
MemoryWorkflowStore
应该已经工作正常了
5.
开始向
HibernateWorkflowStore
转移
,
先修改
WEB-INF/classes/
目录下的
osworkflow.xml
,
改为
<persistence class="com.opensymphony.workflow.spi.hibernate.HibernateWorkflowStore">
</persistence>
</persistence>
6.
把一个
Hibernate.cfg.xml
加到
WEB-INF/classes/
下面
,
我用的数据库是
mysql
.
<property name="hibernate.hbm2ddl.auto">update</property>
这句是为了帮你创建数据库表的
,
跑起来后最好去掉
,
不去也没关系
.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- properties -->
<property name="connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="use_outer_join">true</property>
<property name="show_sql">true</property>
<property name="use_outer_join">true</property>
<property name="connection.pool_size">10</property>
<property name="statement_cache.size">25</property>
<property name="statement_cache.size">25</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateCurrentStep.hbm.xml"></mapping>
<mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateHistoryStep.hbm.xml"></mapping>
<mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateWorkflowEntry.hbm.xml"></mapping>
<mapping resource="com/opensymphony/module/propertyset/hibernate/PropertySetItemImpl.hbm.xml"></mapping>
<mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateHistoryStep.hbm.xml"></mapping>
<mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateWorkflowEntry.hbm.xml"></mapping>
<mapping resource="com/opensymphony/module/propertyset/hibernate/PropertySetItemImpl.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
</hibernate-configuration>
7.
把
hibernate
的
jar
及
hibernate
所有要到的
jar,
统统加到
WEB-INF/lib/
8.
最后一步
,
修改源程序
.
OsWorkFlow 主要作者 Hani , 认为生成 SessionFactory 的责任并不是 OsWorkFlow 的事情 , 坚持应该是用户 , 或者是服务器生成后 , 传给 HibernateWorkflowStore . 他可能是 Spring 的思想太深了吧 . 我也赶紧开始学习了 . 但是如果这样的话 , 最好加个说明 , 说这个产品的 Hibernate 特性还必须配合 Spring 才行 , 那么我再装一个 . 既然他没有说明 , 我又暂时还打算用 spring, 而我又不想改 web 层任何 代码 , 那么我就只好修改他的源程序 , 在 HibernateWorkflowStore 里面生成一个独一无二的 SessionFactory 了 .
OsWorkFlow 主要作者 Hani , 认为生成 SessionFactory 的责任并不是 OsWorkFlow 的事情 , 坚持应该是用户 , 或者是服务器生成后 , 传给 HibernateWorkflowStore . 他可能是 Spring 的思想太深了吧 . 我也赶紧开始学习了 . 但是如果这样的话 , 最好加个说明 , 说这个产品的 Hibernate 特性还必须配合 Spring 才行 , 那么我再装一个 . 既然他没有说明 , 我又暂时还打算用 spring, 而我又不想改 web 层任何 代码 , 那么我就只好修改他的源程序 , 在 HibernateWorkflowStore 里面生成一个独一无二的 SessionFactory 了 .
修改一是添加下面在开头 :
private static SessionFactory sessionFactory;
//~ Constructors ///
static{
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException("Configuration problem: " + ex.getMessage(), ex);
}
}
static{
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException("Configuration problem: " + ex.getMessage(), ex);
}
}
二是在
init
中
把
sessionFactory
= (SessionFactory) props.get("sessionFactory");
注释
编译
,
生成
class,
放到
osworkflow-2.7.0.jar,
取代原来的
HibernateWorkflowStore.class
,
重启服务器
,OK
| |||
|