在做activiti工作流教程工程的时候,出现了BPMN2 property page'has encountered a problem

【工作流前进之路】Activiti第一步:介绍+实例 - 唐欢——廊坊师范学院九期信息技术提高班
- 博客频道 - CSDN.NET
一.什么是工作流
& & & 工作流这个概念起源于生产组织和办公自动化领域,是针对日常工作主公具有固定程序活动而提出的一个概念,目的是通过将工作分解成定义良好的任务和角色,按照一定的规则和过程来执行这些任务并对其进行监控,达到提供工作效率,更好的控制过程,增强对客户的服务,有效管理业务流程等目的.
& & &&工作流(Workflow),指&业务过程的部分或整体在计算机应用环境下的自动化&.对工作流程及各操作步骤之间业务规则的抽象,概括和描述.工作流建模,则是将工作流程主公的工作如何前后组织在一起的逻辑和规则在计算机中以最恰当的规模进行表示并对其实施计算.
二.主要解决什么问题
& & &&在计算机尚未普及时,许多工作流程采用手工传递纸张表单的方式,一级一级审批签字,工作效率特变低.工作流的出现就是为了解决工作流程需要手工操作,工作效率低的问题,用官方文字来解释就是为了实现某个业务目标,利用计算机在多个参与者之间按某种预定规则自动传递文档,信息或任务.
& & &&最常见的使用工作流的地方就是银行客户排队处理办业务叫号,餐馆点餐,网上买东西.作为一个程序猿,也许你会问这些地方我不用工作流,也照样可以解决,但是当需求发生改变的时候,你怎么去维护你的工作流程部分.直接修改代码的话,维护成本特别高.若是用工作流进行开发的话,维护起来成本就比较低了.
1.提高系统的柔性,适应业务流程的变化.
2.实现更好的业务过程控制,提高顾客的服务质量
3.降低系统开发和维护成本.
四.Activiti框架
& & &&Activiti是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN2.0标准,包括支持对象管理组,面对新技术的机遇,提供了技术实现.
& & &&Activiti的创始人是JBPM5版本之前的创始人,从Jboss离职后开发了一个新的BPM引擎:Activiti,所以Activiti可以说是JBPM4的延续,Activiti强调流程服务的可嵌入性和可扩展性,同时更加强调面向业务人员.
&1.创建配置文件activiti.cfg.xml
& & &&如果没有指定Activiti的配置文件,那么默认情况下Myeclipse将会到CLASSPATH下读取Activiti.cfg.xml文件作为Activiti的配置文件.该文件主要用于配置Activiti的数据库连接属性,具体配置:
&bean id=&processEngineConfiguration&
class=&org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration&&
&property name=&databaseSchemaUpdate& value=&true& /&
&property name=&jdbcUrl& value=&jdbc:mysql://localhost:3306/act& /&
&property name=&jdbcDriver& value=&com.mysql.jdbc.Driver& /&
&property name=&jdbcUsername& value=&root& /&
&property name=&jdbcPassword& value=&123456& /&
&property name=&jobExecutorActivate& value=&true& /&
2.创建流程文件
& & &&这个直接建立ActivitiDiagram ,就可以图形化的规划.但是流程描述文件使用的还是XML语言.图形化的流程文件如下图所示:
3.加载路程文件和启动文件
有了流程引擎的配置文件和流程文件,就可以编写代码启动流程引擎病加载该流程文件.具体代码:
public static voidmain(String[] args) {
// 创建流程引擎
ProcessEngineengine = ProcessEngines.getDefaultProcessEngine();
// 得到流程存储服务组件
RepositoryServicerepositoryService = engine.getRepositoryService();
// 得到运行时服务组件
RuntimeServiceruntimeService = engine.getRuntimeService();
// 获取流程任务组件
TaskServicetaskService = engine.getTaskService();
// 部署流程文件
repositoryService.createDeployment()
.addClasspathResource(&bpmn/First.bpmn&).deploy();
// 启动流程
runtimeService.startProcessInstanceByKey(&myProcess&);
// 查询第一个任务
Tasktask = taskService.createTaskQuery().singleResult();
System.out.println(&第一个任务完成前,当前任务名称:& + task.getName());
// 完成第一个任务(流程结束)
plete(task.getId());
// 查询第二个任务
task =taskService.createTaskQuery().singleResult();
System.out.println(&第二个任务完成前,当前任务名称:& + task.getName());
// 完成第二个任务(流程结束)
plete(task.getId());
task= taskService.createTaskQuery().singleResult();
System.out.println(&流程结束后,查找任务:& + task);
& & &&因为Activiti有很多地方都有JBPM的影子,目前关于Acitiviti的资料相对于JBPM来说要少一些,想要学习Activiti的朋友,可以先学习JBPM,这样就会容易很多.学习是一个融会贯通的过程,在学习Acitiviti的时候,总结与JBPM的相同,区分JBPM的不同,结成知识网.
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:146596次
积分:8740
积分:8740
排名:第846名
原创:184篇
评论:2445条
阅读:6299
(4)(4)(4)(5)(4)(4)(4)(4)(5)(4)(4)(4)(4)(5)(4)(4)(5)(4)(4)(4)(6)(5)(3)(4)(4)(6)(4)(4)(6)(2)(8)(13)(6)(9)(12)(4)(2)(2)浅谈activiti工作流 -
- ITeye技术网站
博客分类:
本文档是我综合了“前人”的经验以及我自己的一点儿心得所写。里面清楚的讲述了activiti从环境配置到真正项目的运行的详细过程。本人自知能力有限,发表此文章,有两个目的:第一,希望高人能指教一二;第二,供自己以后...
一:环境配置(前提:JBK、Tomcat和Eclispe、myeclipse已经安装好)
JDK1.5以上版本
Ant 1.8.1以上版本,运行自带的Demo必须.
Ant 的安装:
1、下载ant,并解压到E:\apache-ant-1.8.2&&&& http://ant.apache.org/bindownload.cgi 2、配置环境变量&&
& %ANT_HOME%:E:\apache-ant-1.8.2 (这里为你自己解压缩的目录)
& PATH:%ANT_HOME%\bin(这个设置是为了方便在dos环境下操作)
3、检测是否安装成功&
Activiti的安装:(下载的是整好的项目)
1、下载activiti-5.5.zip,并解压到E:\activiti-5.5&&&&& http://www.activiti.org/download.html 2、运行脚本,设置 Activiti 环境?
& 打开DOS窗口,cd到setup目录。
?输入 ant demo.start,然后按 enter 键。
?脚本完成后,会在浏览器内启动所有的 Activiti 的 web 应用。以 kermit/kermit 登陆。
引用
注意:在执行ant demo.start时,如果更换数据库,比如mysql(默认是H2),需要更新如下文件
1.build.properties
# The db property should refer to the type of database that&&
# you want to use. Currently h2, MySQL(mysql),&
# Postgres SQL(postgres) and Oracle 10g (oracle) is supported.&
# SQL Server(mssql) is also supported, but is an EXPERIMENTAL feature.&
# IBM DB2(db2) is also supported, but is an EXPERIMENTAL feature.&
# When using oracle, follow the instructions described in the userguide, chapter&
# Configuration & Changing the database & Using Oracle in the demo setup&
# The tx property refers to the transaction environment&
# you want to use.& Choose from {standalone}&
tx=standalone&
# Specify the version of Tomcat that you want to use.&
# We only tested with the given Tomcat version but in&&
# theory any tomcat 6.0.x version should do fine.&
tomcat.version=6.0.32&
# If you have tomcat already downloaded, point the&&
# downloads.dir property to that directly.& If tomcat is&&
# not found in the downloads.dir, it will be automatically&&
# downloaded there.&
# The downloads directory should be outside of /target/&
# to avoid re-downloading after a clean&
downloads.dir=../../downloads&
# Remove this property or set it to disabled if you're not using Activiti Cycle&
feature.cycle=enabled&
# Remove this property or set it to disabled if you're not using Activiti Modeler&
feature.modeler=enabled&
& 修改数据库类型为mysql&& 打开文件“setup\build.properties”修改db=mysql(默认为h2) 2、build.mysql.properties
jdbc.driver=com.mysql.jdbc.Driver&
jdbc.url=jdbc:mysql://IP地址:3306/activiti?autoReconnect=true&
jdbc.username=所用数据库的用户名&
jdbc.password=所用数据库的密码&
遇到的问题:
一直提示9092端口被占用,其实本机上没有任何程序运行在端口9092,可以通过命令查看:netstat -an而且异常中提示的url不一定是tcp://localhost:9092,localhost可能是其他ip,最关键的就在这里,为什么会出现其他IP呢? 原因是在本机安装的了Vmware workstation,本机会出现三个网卡,如是就会出现异常。 把本机的两个虚拟网卡禁用就OK了。 这个问题比较难找到真实原因,因为问题提示太有误导性port may be in use
2、执行“ant demo.start”之前,需要创建数据库,否则会出现下边的问题:
3、执行“ant demo.start”完毕之后,自带的web应用访问不了,如下图:
原因:activiti-modeler-5.5.war不会自动发布,导致访问不了
(自己写)安装Activiti的Eclipse或者myeclipse插件 直接Update就行 http://activiti.org/designer/update/
Eclipse 3.6.2以上版本
Myeclipse8.5或者myeclipse 9.0版本的
支持的数据库
以下是Activiti使用参考数据库类型(区分大小写!)。
Activiti数据库类型 版本测试 JDBC URL示例 注释
H2 1.2.132 jdbc:h2:tcp://localhost/activiti 默认配置的数据库
MySQL 5.1.11 jdbc:mysql://localhost:3306/activiti 测试使用的mysql - connetor Java数据库驱动程序
Oracle 10.2.0 jdbc:oracle:thin:@localhost:1521:xe
POSTGRES 8.4 jdbc:postgresql://localhost:5432/activiti
DB2 DB2 9.7中使用db2jcc4 jdbc:db2://localhost:50000/activiti
MSSQL 2008使用JDBC JTDS - 1.2.4 jdbc:jtds:sqlserver://localhost:1433/activiti
·下面的是数据库表结构:
一、数据库建表:
&&&&& 建表说明目前省略
数据库表的命名
Acitiviti数据库中表的命名都是以ACT_开头的。第二部分是一个两个字符用例表的标识。此用例大体与服务API是匹配的。
ACT_RE_*:’RE’表示repository。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
ACT_RU_*:’RU’表示runtime。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。Activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
ACT_ID_*:’ID’表示identity。这些表包含标识的信息,如用户,用户组,等等。
ACT_HI_*:’HI’表示history。就是这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。
ACT_GE_*:普通数据,各种情况都使用的数据。
二、数据库表结构说明:
1、用建模工具反向出来的数据库表结构图如下:
2、数据库表结构说明:
·&&&&&&&&&&&& ACT_GE_PROPERTY:属性数据表。存储整个流程引擎级别的数据。
1. NAME_:属性名称
2. VALUE_:属性值
3. REV_INT:版本号?
·&&&&&&&&&&&& ACT_GE_BYTEARRAY:用来保存部署文件的大文本数据的。
1. ID_:资源文件编号,自增长
2. REV_INT:版本号?
3. NAME_:资源文件名称
4. DEPLOYMENT_ID_:来自于父表ACT_RE_DEPLOYMENT中的主键
5. BYTES_:大文本类型,存储文本字节流
·&&&&&&&&&&&& ACT_RE_DEPLOYMENT:用来存储部署时需要被持久化保存下来的信息。
1. ID_:部署编号,自增长
2. NAME_:部署的包名称
3. DEPLOY_TIME_:部署时间
·&&&&&&&&&&&& ACT_RE_PROCDEF:业务流程定义数据表。
1. ID_:流程ID,由“流程编号:流程版本号:自增长ID ” 组成
2. CATEGORY_:流程命令空间(该编号就是流程文件targetNamespace的属性值)
3. NAME_:流程名称(该编号就是流程文件process元素的name属性值)
4. KEY_:流程编号(该编号就是流程文件process元素的id属性值)
5. VERSION_:流程版本号(由程序控制,新增即为1,修改后依次加1来完成的)
6. DEPLOYMENT_ID_:部署编号
7. RESOURCE_NAME_:资源文件名称
8. DGRM_RESOURCE_NAME_:图片资源文件名称
9. HAS_START_FORM_KEY_:是否有Start Form Key。
注意:此表与ACT_RE_DEPLOYMENT是多对一的关系,即,一个部署的bar包里可能包含多个流程定义文件,每个流程定义文件都会有一条记录在ACT_RE_PROCDEF表内,每条流程定义的数据,都会对应ACT_GE_BYTEARRAY表内的一个资源文件和PNG图片文件。与ACT_GE_BYTEARRAY的关联是通过程序用ACT_GE_BYTEARRAY.NAME_与ACT_RE_PROCDEF.RESOURCE_NAME_完成的,在数据库表结构内没有体现。
·&&&&&&&&&&&& ACT_ID_GROUP:用来保存用户组信息。
1. ID_:用户组名
2. REV_INT:版本号?
3. NAME_:用户组描述信息
4. TYPE_:用户组类型
·&&&&&&&&&&&& ACT_ID_MEMBERSHIP:用来保存用户分组信息。
1. USER_ID_:用户名
2. GROUP_ID_:用户组名
·&&&&&&&&&&&& ACT_ID_USER:用来保存用户信息。
1. ID_:用户名
2. REV_INT:版本号?
3. FIRST_:用户名称
4. LAST_:用户姓氏
5. EMAIL_:邮箱
6. PWD_:登录密码
·&&&&&&&&&&&& ACT_RU_EXECUTION:
2. REV_:版本号?
3. PROC_INST_ID_:流程实例编号
4. BUSINESS_KEY_:业务编号
5. PARENT_ID_:
6. PROC_DEF_ID_:流程ID
7. SUPER_EXEC_:
8. ACT_ID_:
9. IS_ACTIVE_:
10.&&&&&&&&&&& IS_CONCURRENT_:
11.&&&&&&&&&&& IS_SCOPE_:
·&&&&&&&&&&&& ACT_RU_JOB:运行时定时任务数据表。
3. TYPE_:
4. LOCK_EXP_TIME_:
5. LOCK_OWNER_:
6. EXCLUSIVE_:
7. EXECUTION_ID_:
8. PROCESS_INSTANCE_ID_:
9. RETRIES_:
10.&&&&&&&&&&& EXCEPTION_STACK_ID_:
11.&&&&&&&&&&& EXCEPTION_MSG_:
12.&&&&&&&&&&& DUEDATE_:
13.&&&&&&&&&&& REPEAT_:
14.&&&&&&&&&&& HANDLER_TYPE_:
15.&&&&&&&&&&& HANDLER_CFG_:
·&&&&&&&&&&&& ACT_RU_TASK:运行时任务数据表。
3. EXECUTION_ID_:
4. PROC_INST_ID_:
5. PROC_DEF_ID_:
6. NAME_:
7. DESCRIPTION_:
8. TASK_DEF_KEY_:
9. ASSIGNEE_:
10.&&&&&&&&&&& PRIORITY_:
11.&&&&&&&&&&& CREATE_TIME_:
·&&&&&&&&&&&& ACT_RU_IDENTITYLINK:任务参与者数据表。主要存储当前节点参与者的信息。
3. GROUP_ID_:
4. TYPE_:
5. USER_ID_:
6. TASK_ID_:
·&&&&&&&&&&&& ACT_RU_VARIABLE:运行时流程变量数据表。
3. TYPE_:
4. NAME_:
5. EXECUTION_ID_:
6. PROC_INST_ID_:
7. TASK_ID_:
8. BYTEARRAY_ID_:
9. DOUBLE_:
10.&&&&&&&&&&& LONG_:
11.&&&&&&&&&&& TEXT_:
12.&&&&&&&&&&& TEXT2_:
·&&&&&&&&&&&& ACT_HI_PROCINST:
·&&&&&&&&&&&& ACT_HI_ACTINST:
·&&&&&&&&&&&& ACT_HI_TASKINST:
·&&&&&&&&&&&& ACT_HI_DETAIL:
3、结论及改造建议
&
流程文件部署主要涉及到3个表,分别是:ACT_GE_BYTEARRAY、ACT_RE_DEPLOYMENT、ACT_RE_PROCDEF。主要完成“部署包”--&“流程定义文件”--&“所有包内文件”的解析部署关系。从表结构中可以看出,流程定义的元素需要每次从数据库加载并解析,因为流程定义的元素没有转化成数据库表来完成,当然流程元素解析后是放在缓存中的,具体的还需要后面详细研究。
流程定义中的java类文件不保存在数据库里 。
组织机构的管理相对较弱,如果要纳入单点登录体系内还需要改造完成,具体改造方法有待研究。
运行时对象的执行与数据库记录之间的关系需要继续研究
历史数据的保存及作用需要继续研究。
Act_Execution Act_task Act_TaskInvolement Act_Job Act_Variable这五张表。 这五张表在执行完所谓的”部署“逻辑后,是不会被填上任何值的。那什么时候这些表会被填充上值呢? 当我们根据一个叫做ProcessService(在jBPM中,这个类是ExecutionService)的类,来真正启动(Start)一个流程 时,这些表中才会被根据你定义的流程定义,填充上相应的记录。 一个不精确的比喻,在Activiti中,流程定义和流程执行实例,就像Java中的Class何Class Instance关系一样,根据一个流程定义,可以启动多个流程实例,供不同业务需求使用;一个类,当然可以有多个运行时实例,供不同需求使用。 需要多说一点,Act_TaskInvolement这张表直译过来就是,任务参与者,所以它存的是:和一个流程中,一个具体动作(Activity)相 关的用户(User)和角色(Group)的信息,即:当前节点参与者的信息。其他的表,也可以顾名思义了吧,就是存和一个具体动作相关的参数以及作业的 信息。& 最后强调一点:这五张表有点像即擦即用的Flash存储介质哦。 什么意思,一个流程假设有多个动作(任务、节点......叫啥也行)组成,那么这五张表只是存储当前流程实例中,”活动(Active)行为“的相关数 据,如果现在活动的行为已经从A节点流到B节点了,那么,与A节点相关的所有信息是会从这4张表(不包含Act_Execution,流程实例全部完成, 相关记录才会删除;而不是一个动作完成)中被删除的!!!!
Activiti的持久化方式:
Activiti使用Mybatis3做持久化工作,可以在配置中设置流程引擎启动时创建表。
Activiti-administrator:自带的用户管理系统,维护用户和组,需要配置数据连接参数,在activiti-administrator\WEB-INF\applicationContext.xml中,并加入JDBC驱动包。
Activiti-cycle:PVM活动检测的,由activiti-rest提供服务,不需配置。
Activiti-explorer:可以查看用户任务和启动流程,由activiti-rest提供服务,不需配置。
Activiti-kickstart:简单的点对点流程定义维护工具,需要配置数据连接,把activiti.cfg.xml文件放在classes下,并加入驱动包
Activiti-modeler:在线编辑和维护流程定义的工具,最后以文件夹的方式部署,需要配置:activiti-modeler\WEB-INF\classes\configuration.properties文件。
Activiti-probe:PVM的观测服务,由activiti-rest提供服务,不需配置。可以查看deployment、processdefinition、processinstance、database。
Activiti-rest:其它几个应用的服务提供者,需要配置数据连接,把activiti.cfg.xml文件放在classes下,并加入驱动包。
关键对象:
Deployment:流程部署对象,部署一个流程是创建。
processDefinitions:流程定义,部署成功后自动创建。
ProcessInstances:流程实例,启动流程是创建。
Task:任务,在activiti中的task仅指有角色参与的任务,即定义中的UserTask。
Execution:执行计划,流程实例和流程执行中的所有节点都是Execution,如UserTask、ServiceTask等。
服务接口:
ProcessEngine:流程引擎接口,提供流程管理和运作的所有接口。
RuntimeService:运行时服务接口,提供流程启动服务,运行中流程查询,运行变量设置和获取。
TaskService:用户任务接口(UserTask),提供运行时任务查询、领取、完成、删除及变量设置用户管理等服务。
IdentityService:用户和组管理接口。
ManagementService:流程引擎管理接口。
HistoryService:流程处理查询接口,包括执行中流程查询和历史流程查询。
简单入门:
Activiti的实用意义: Activiti是JBPM的原创者的团队编写的,实际上它才是JBPM“血统”的继承者。而如今的JBPM5所用的几乎是Drools Flow的源码。因此一直在用JBPM的用户更倾向于使用Activiti,需要注意的是Activiti用的是BPMN的流程定义语言BPEL而非当初 的JBDL了。 二、Activiti的designer在eclipse中的安装: 打开 Help?Install New Software。在如下面板中,点击 Add 按钮,然后填写下列字段:& Name:Activiti BPMN 2.0 designer Location:http://activiti.org/designer/update/& 务必不要选中”Contact all updates sites..”,因为所有必需的插件都能从 Activiti 更新站点下载。 三、Activiti整合MySql数据库的方法 要将演示程序设置配置到不同的数据库,或生成不同的数据库的配置文件,按如下步骤: ?& 编辑 setup/build.propertyies,将 db 参数修改成你的数据库类型{oracle | mysql | postgres | h2 | db2 | mssql}。 编辑 setup/build.${db}.propertyies,将 JDBC 连接参数修改成你安装的数据库的参数。 要想根据你在 build.*.properties 文件指定的属性来创建数据的配置文件,请在(开始-&运行-&CMD)setup 文件内运行:& ant cfg.create 可以在 setup/build/activti.cfg 内找到生成的配置文件。同时,方便起见,可以在 setup/build 下找到包含了配置文件的 jar 文件 activiti-cfg.jar。 四、部署Activiti实例和Activiti的web designer部署 打开控制台,ant demo.start 这时则开始建立数据库,部署实例到eclipse,部署designer到tomcat服务器,这里的tomcat服务器在{%activiti-5.6%}\apps\apache-tomcat-6.0.32下。 如果之前更改了数据库, Eclipse中需要将实例的配置文件activiti.cfg.xml的内容改为{%activiti-5.6%}\setup\build\activiti-cfg\activiti.cfg.xml的内容。 为了使Activiti KickStart 能够正常运行,我们需要单独更改它的数据库驱动程序activiti.cfg.jar (正确配置的jar位于{%activiti-5.6%}/setup/build/下) ,并将其置于apps/apache-tomcat-6.x/webapps/activiti-kickstart/WEB-INF/lib 文件夹下。同样,必须将数据库驱动程序置于同一文件夹下。 可以在 setup/files/dependencies/libs/下找到你的数据库驱动程序(除了 Oracle)。 五、Activiti web designer以及部署到eclipse的实例介绍 应用名称 URL 描述 Activiti Probe http://localhost:8080/activiti-probe 管理员管理控制台。使用该工具查看配置好的流程引擎是否正确初始化,以及数据库内容。 Activiti Explorer http://localhost:8080/activiti-explorer 流程引擎用户控制台。使用该工具查看您的个人任务、候选人任务,以及完成的任务。 Activiti Cycle http://localhost:8080/activiti-cycle Activiti 协助工具。使用该工具浏览资料库以及执行模型格式之间的转换。 Activiti Modeler http://localhost:8080/activiti-modeler 基于Web 的流程设计工具。使用该工具绘制BPMN2.0 规范的流程定义文件。(对浏览器有版本要求) Activiti KickStart http://localhost:8080/activiti-kickstart Activiti KickStart 是利用 Activiti 引擎的可用构造的子集来快速创建’临时安排的(adhoc)’业务流程的一个基于 web 的工具。& activiti-engine-examples:该套示例展示了 Activiti 最常用的用法:BPMN 流程定义和流程的执行被存储在数据库中, 并且示例中使用了持久化 API。 ? activiti-spring-examples:这些示例展示了在 Spring 环境下如何使用 Activiti 引擎。 ? activiti-groovy-examples:这些示例展示了 groovy 的依赖库以及一个使用 groovy 脚本的流程。 ? activiti-jpa-examples:这些示例展示了依赖库以及 Activiti 中如何使用 JPA。 ? activiti-cxf-examples:这些示例展示了依赖库以及在 Activiti 中如何使用 web 服务。 ? activiti-cycle-examples:此项目内含有一个关于 Activiti Cycle 的演示示例。 ? activiti-modeler-examples:在演示程序安装内 Activiti Modeler 配置的模型库文件。
通过 ProcessEngineBuilder& 读取 activiti 的配置文件,就可以生成流程引擎实例。
通过流程引擎实例 processEngine, 我们就可以通过 getXXXService() 取得各种包含 workflow/BPM& 方法的 service 。
RepositoryService& : 提供方法获取各种流程和部署文件的信息 .
TaskService :& 提供对任务相关的各种操作
identityService :& 管理用户和用户组。
FormService :& 获取或者绑定数据到流程实例上
RuntimeService :& 提供操作部署文件,流程文件和流程实例的方法 .
ManagementService :& 提供管理员对流程引擎的监控,和流程引擎服务应用无关。
HistoryService :& 提供正在执行和过去执行的各种流程实例信息
ProcessEngines.getDefaultProcessEngine()会在第一次被调用时初始并构建process engine,接下来对该方法的调用返回的都
是同一个流程引擎。利用ProcessEngines.init()、ProcessEngines.destroy()可以正确创建、关闭流程引擎。
ProcessEngines 会浏览所有activiti.cfg.xml 和activiti-context.xml 文件。对于那些activiti.cfg.xml 文件,将以Activiti 特有的方
式来构建流程引擎:
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine()。对于那些
activiti-context.xml 文件,将以Spring& 的方式来构建流程引擎:首先,创建spring 应用上下文;然后,从该上下文中获取流程引擎。
绘制流程图
创建完后会发现它自动把流程图放到main.resources.diagrams 包下面了,如果不想放在这下面可以直接移动过去。本人移动到了activiti.process.def包下面,这样比较符合编码规范。
接下来就是打开创建的流程图,开始绘制了。
按照上面绘制完后,就该编写相应的代码了。
package activiti.&
import org.activiti.engine.delegate.DelegateE&
import org.activiti.engine.delegate.JavaD&
public class ProcessHelloWorld implements JavaDelegate {&
&&& @Override&
&&& public void execute(DelegateExecution arg0) throws Exception {&
&&&&&&& System.out.println("HelloWorld");&
然后给 HelloWorld这个节点指定相应的执行相应的代码,需要打开流程图HelloWorld.activiti 然后点击HelloWorld节点 在下面的点开Main config选项卡里面指定Service class 为刚才写的流程代码。这样当流程走到这一步的时候就会执行这个类里面的execute方法。
接下来咱们需要做的就是发布流程以及启动流程了。
编写ProcessUtil封装一些方法,方便调用。
package activiti.&
import java.util.HashM&
* 与流程有关的工具类
public class ProcessUtil {&
&&&& * 发布流程的方法
&&& public static void deploy() {&
&&&&&&& RepositoryService service = (RepositoryService) CommonUtil.getBean("repositoryService");&
&&&&&&& service.createDeployment().addClasspathResource("activiti/process/def/HelloWorld.bpmn20.xml")&
&&&&&&&&&&&&&&& .addClasspathResource("activiti/process/def/HelloWorld.png").deploy();&
&&&& * 启动流程
&&& public static String start() {&
&&&&&&& RuntimeService service = (RuntimeService) CommonUtil.getBean("runtimeService");&
&&&&&&& ProcessInstance instance = service.startProcessInstanceByKey("HelloWorld");&
&&&&&&& return instance.getProcessInstanceId();&
CommonUtil代码
public class CommonUtil implements ApplicationContextAware {&
&&& private static ApplicationContext springFactory =&
&&& public static Object getBean(String name) {&
&&&&&&& return springFactory.getBean(name);&
&&& public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {&
&&&&&&& springFactory = applicationC&
编写相应的servlet
public class ProcessAction extends HttpServlet {&
private static final long serialVersionUID = 1L;&
public ProcessAction() {&
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse
*&&&&& response)
@Override&
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {&
String cmd = request.getParameter("cmd");&
String page =&
if ("deploy".equals(cmd)) {&
ProcessUtil.deploy();&
request.setAttribute("result", "流程发布成功");&
page = "success.jsp";&
} else if ("start".equals(cmd)) {&
String id = ProcessUtil.start();&
request.setAttribute("result", "流程启动成功,流程ID:" + id);&
page = "success.jsp";&
request.getRequestDispatcher(page).forward(request, response);&
相应的页面index.jsp
[html]view plaincopyprint?
&%@ page language="java" contentType="text/ charset=utf-8"&
&&& pageEncoding="utf-8"%&&
&!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&&
&meta http-equiv="Content-Type" content="text/ charset=utf-8"&&
&title&流程测试&/title&&
&&& &form action="process" method="post"&&
&&&&&&& &input type="radio" name="cmd" value="deploy"&发布流程&/input&&&
&&&&&&& &input type="radio" name="cmd" value="start"&启动流程&/input&&&
&&&&&&& &input type="radio" name="cmd" value="view"&查看当前启动用户流程&/input&&&
&&&&&&& &input type="submit" value="提交"&&
&&& &/form&&
success.jsp
[html]view plaincopyprint?
&%@ page language="java" contentType="text/ charset=utf-8"&
&&& pageEncoding="utf-8"%&&
&!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&&
&meta http-equiv="Content-Type" content="text/ charset=utf-8"&&
&title&成功&/title&&
&&& 处理结果:&%=request.getAttribute("result") %&&
&&& &a href="index.jsp"&返回&/a&&
web.xml配置
&?xml version="1.0" encoding="UTF-8"?&&
&web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="/xml/ns/javaee" xmlns:web="/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="/xml/ns/javaee /xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"&&
& &context-param&&
&&& &param-name&contextConfigLocation&/param-name&&
&&& &param-value&&
&span style="white-space:pre"&&&& &/span&classpath*:*.xml&
&&& &/param-value&&
& &/context-param&&
& &listener&&
&&& &listener-class&&
&&&&&&&&&&& org.springframework.web.context.ContextLoaderListener&
&&&&&&& &/listener-class&&
& &/listener&&
& &servlet&&
&&& &servlet-name&ProcessAction&/servlet-name&&
&&& &servlet-class&com.hollycrm.servlet.ProcessAction&/servlet-class&&
& &/servlet&&
& &servlet-mapping&&
&&& &servlet-name&ProcessAction&/servlet-name&&
&&& &url-pattern&/process&/url-pattern&&
& &/servlet-mapping&&
&/web-app&
至此编码工作已经全部完成,发布应用进入index.jsp,首先点击发布流程。然后再点击启动流程。看看是不是控制台输出了HelloWorld! 因为ServiceTask
为自动任务不需要人工干预,所以会自动执行。启动流程以后直接进入到了HellorWorld执行完后流程也就结束了。
在activiti中每一个用户属于一个用户组,不同的用户拥有不同的权限,不同的权限可以有不同的操作,因此请求的资源路径和登录的安全验证相当的重要。需要添加相关的验证。
&&&&&& 原理实现REST的org.restlet.Application接口实现,实现REST访问方式唯一的入口点,同时添加相关的权限验证。然后再web.xml配置即可。
web.xml配置如下:&?xml version="1.0" encoding="UTF-8"?&&
&web-app id="WebApp_ID" version="2.4"&
&&&&&&&&&&& xmlns="/xml/ns/j2ee"&
&&&&&&&&&&& xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&
&&&&&&&&&&& xsi:schemaLocation="/xml/ns/j2ee&
&&&&&&&&&&&&&&&& /xml/ns/j2ee/web-app_2_4.xsd"&&
& &display-name&Activiti REST&/display-name&
&&
& &listener&
&&& &listener-class&org.activiti.rest.servlet.ActivitiServletContextListener&/listener-class&
& &/listener&
& &!-- Restlet adapter --&&
& &servlet&&
&&& &servlet-name&RestletServlet&/servlet-name&&
&&& &servlet-class&org.restlet.ext.servlet.ServerServlet&/servlet-class&
&&& &init-param&
&&&&& &!-- Application class name --&
&&&&& &param-name&org.restlet.application&/param-name&
&&&&& &param-value&org.activiti.rest.application.ActivitiRestApplication&/param-value&
&&& &/init-param&
& &/servlet&
&
& &!-- Catch all requests --&&
& &servlet-mapping&&
&&& &servlet-name&RestletServlet&/servlet-name&&
&&& &url-pattern&/service/*&/url-pattern&&
& &/servlet-mapping&&
&/web-app&
代码如下:
package org.activiti.rest.
import org.activiti.rest.api.ActivitiU
import org.activiti.rest.api.DefaultR
import org.activiti.rest.api.engine.ProcessEngineR
import org.activiti.rest.api.identity.GroupR
import org.activiti.rest.api.identity.GroupUsersR
import org.activiti.rest.api.identity.LoginR
import org.activiti.rest.api.identity.UserGroupsR
import org.activiti.rest.api.identity.UserPictureR
import org.activiti.rest.api.identity.UserR
import org.activiti.rest.api.identity.UserSearchR
import org.activiti.rest.api.management.JobExecuteR
import org.activiti.rest.api.management.JobR
import org.activiti.rest.api.management.JobsExecuteR
import org.activiti.rest.api.management.JobsR
import org.activiti.rest.api.management.TableDataR
import org.activiti.rest.api.management.TableR
import org.activiti.rest.api.management.TablesR
import org.activiti.rest.api.process.ProcessDefinitionFormR
import org.activiti.rest.api.process.ProcessDefinitionPropertiesR
import org.activiti.rest.api.process.ProcessDefinitionsR
import org.activiti.rest.api.process.ProcessInstanceDiagramR
import org.activiti.rest.api.process.ProcessInstanceR
import org.activiti.rest.api.process.ProcessInstancesR
import org.activiti.rest.api.process.StartProcessInstanceR
import org.activiti.rest.api.repository.DeploymentDeleteR
import org.activiti.rest.api.repository.DeploymentUploadR
import org.activiti.rest.api.repository.DeploymentsDeleteR
import org.activiti.rest.api.repository.DeploymentsR
import org.activiti.rest.api.task.TaskAddR
import org.activiti.rest.api.task.TaskAttachmentAddR
import org.activiti.rest.api.task.TaskAttachmentR
import org.activiti.rest.api.task.TaskFormR
import org.activiti.rest.api.task.TaskOperationR
import org.activiti.rest.api.task.TaskPropertiesR
import org.activiti.rest.api.task.TaskR
import org.activiti.rest.api.task.TaskUrlAddR
import org.activiti.rest.api.task.TasksR
import org.activiti.rest.api.task.TasksSummaryR
import org.restlet.A
import org.restlet.R
import org.restlet.R
import org.restlet.R
import org.restlet.data.ChallengeS
import org.restlet.routing.R
import org.restlet.security.ChallengeA
import org.restlet.security.SecretV
import org.restlet.security.V
* @author Tijs Rademakers
*/
public class ActivitiRestApplication extends Application {
&
& private ChallengeAuthent
& /**
&& * Creates a root Restlet that will receive all incoming calls.
&& */
& @Override
& public synchronized Restlet createInboundRoot() {
&&& Verifier verifier = new SecretVerifier() {
&&&&& @Override
&&&&& public boolean verify(String username, char[] password) throws IllegalArgumentException {
&&&&&&& boolean verified = ActivitiUtil.getIdentityService().checkPassword(username, new String(password));
&&&&&&&
&&&&& }
&&& };
&&& authenticator = new ChallengeAuthenticator(null, true, ChallengeScheme.HTTP_BASIC,
&&&&&&&&& "Activiti Realm") {
&&&&&
&&&&& @Override
&&&&& protected boolean authenticate(Request request, Response response) {
&&&&&&& if (request.getChallengeResponse() == null) {
&&&&&&&&&
&&&&&&& } else {
&&&&&&&&& return super.authenticate(request, response);
&&&&&&& }
&&&&& }
&&& };
&&& authenticator.setVerifier(verifier);
&&&
&&& Router router = new Router(getContext());
&&& router.attachDefault(DefaultResource.class);
&&&
&&& router.attach("/process-engine", ProcessEngineResource.class);
&&&
&&& router.attach("/login", LoginResource.class);
&&&
&&& router.attach("/user/{userId}", UserResource.class);
&&& router.attach("/user/{userId}/groups", UserGroupsResource.class);
&&& router.attach("/user/{userId}/picture", UserPictureResource.class);
&&& router.attach("/users/{searchText}", UserSearchResource.class);
&&&
&&& router.attach("/group/{groupId}", GroupResource.class);
&&& router.attach("/groups/{groupId}/users", GroupUsersResource.class);
&&&
&&& router.attach("/process-definitions", ProcessDefinitionsResource.class);
&&& router.attach("/process-instances", ProcessInstancesResource.class);
&&& router.attach("/process-instance", StartProcessInstanceResource.class);
&&& router.attach("/processInstance/{processInstanceId}", ProcessInstanceResource.class);
&&& router.attach("/processInstance/{processInstanceId}/diagram", ProcessInstanceDiagramResource.class);
&&& router.attach("/process-definition/{processDefinitionId}/form", ProcessDefinitionFormResource.class);
&&& router.attach("/process-definition/{processDefinitionId}/properties", ProcessDefinitionPropertiesResource.class);
&&&
&&& router.attach("/tasks", TasksResource.class);
&&& router.attach("/tasks-summary", TasksSummaryResource.class);
&&& router.attach("/task", TaskAddResource.class);
&&& router.attach("/task/{taskId}", TaskResource.class);
&&& router.attach("/task/{taskId}/form", TaskFormResource.class);
&&& router.attach("/task/{taskId}/attachment", TaskAttachmentAddResource.class);
&&& router.attach("/task/{taskId}/url", TaskUrlAddResource.class);
&&& router.attach("/task/{taskId}/{operation}", TaskOperationResource.class);
&&&
&&& router.attach("/attachment/{attachmentId}", TaskAttachmentResource.class);
&&&
&&& router.attach("/form/{taskId}/properties", TaskPropertiesResource.class);
&&&
&&& router.attach("/deployments", DeploymentsResource.class);
&&& router.attach("/deployment", DeploymentUploadResource.class);
&&& router.attach("/deployments/delete", DeploymentsDeleteResource.class);
&&& router.attach("/deployment/{deploymentId}", DeploymentDeleteResource.class);
&&&
&&& router.attach("/management/jobs", JobsResource.class);
&&& router.attach("/management/job/{jobId}", JobResource.class);
&&& router.attach("/management/job/{jobId}/execute", JobExecuteResource.class);
&&& router.attach("/management/jobs/execute", JobsExecuteResource.class);
&&&
&&& router.attach("/management/tables", TablesResource.class);
&&& router.attach("/management/table/{tableName}", TableResource.class);
&&& router.attach("/management/table/{tableName}/data", TableDataResource.class);
&&&
&&& authenticator.setNext(router);
&&&
& public String authenticate(Request request, Response response) {
&&& if (!request.getClientInfo().isAuthenticated()) {
&&&&& authenticator.challenge(response, false);
&&&&&
&&& }
&&& return request.getClientInfo().getUser().getIdentifier();
& }
}
浏览: 3200 次
来自: 北京
请问能使用ibatis2+spring 2.5.6结合acit ...}

我要回帖

更多关于 activiti工作流原理 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信