原标题:基于工作流的平台管理体系规划

Activiti专门的学业流引擎使用

图片 1

1.轻松介工作流引擎与Activiti

对此专业流引擎的演说请参见百度健全:办事流引擎

1.轻巧介专门的工作流引擎与Activiti

对于专门的学问流引擎的分解请参谋百度宏观:工作流引擎

对于互连网经济平台来讲,主要的作业愈发是关联资金业务有关操作时都有供给有相关的审查批准流程.同期在流水生产线的流转进度中需求和一一业务系统实行交互,完结真正的事体管理,
并记录那些进程中全数人的操作以及每一步操作时所波及数额快速照相,以便于内外界审计和主题材料的追溯.

1.1 作者与工作流引擎

在首家协作社职业的时候根本职务正是开拓OA系统,当然基本都以有专门的学业流的支撑,然而当下使用的行事流引擎是集团部分牛人开荒的(听他们讲是用三个开源的引擎修改的),名称为CoreFlow;效率相对Activiti来讲相比较弱,不过能满意经常的行使,当然也是有成百上千的主题材料由此后来我们只好修改引擎的代码打补丁。

未来是自己专门的学问的第二家商厦,因为要开辟ERP、OA等系统供给选拔职业流,在品种实验研讨阶段本身先找找资料选用选取哪个开源行事流引擎,最终明确了Activiti5并依附商家的架构做了一部分DEMO。

1.1 小编与做事流引擎

在率先家合营社做事的时候根本职分就是开辟OA系统,当然基本都以有专门的学业流的支撑,不过当下采用的职业流引擎是集团部分牛人开拓的(传说是用三个开源的引擎修改的),名为CoreFlow;作用相对Activiti来讲比较弱,不过能满足常常的应用,当然也会有多数的标题因而后来大家不得不修改引擎的代码打补丁。

目前是自身专门的学问的第二家商厦,因为要开拓ERP、OA等种类必要使用专门的学业流,在品种应用探讨阶段本人先找找资料选用选取哪个开源干活流引擎,最后分明了Activiti5并基于商家的架构做了部分DEMO。

◆✦上边为多个独立的业务流程✦◆

1.2 Activiti与JBPM5?

对此Activiti、jBPM4、jBPM5我们理应怎样挑选,在InfoQ上有一篇文章写的很好,从大的范畴相比较各样引擎之间的反差,请参见文章:纵观jBPM:从jBPM3到jBPM5以及Activiti5

1.2 Activiti与JBPM5?

对此Activiti、jBPM4、jBPM5大家应有怎么样抉择,在InfoQ上有一篇小说写的很好,从大的框框相比各种引擎之间的差异,请参见小说:纵观jBPM:从jBPM3到jBPM5以及Activiti5

(注: 为了证实方便, 已经简化和修改相关手续, 和点融实操不一样等)

1.3 Activiti资料

  • 官网:

  • 下载:

  • 本子:Activiti的本子是从5开始的,因为Activiti是使用jBPM4的源码;本子公布:多少个月宣布三次。

  • Eclipse Plugin: 

  • Activit中文群:5435716

1.3 Activiti资料

  • 官网:

  • 下载:

  • 本子:Activiti的版本是从5开始的,因为Activiti是使用jBPM4的源码;本子公布:三个月宣布三遍。

  • Eclipse Plugin: 

  • Activit中文群:236540304

图片 2

2.初次使用境遇标题采摘

因为Activiti刚刚退出不久所以资料相比较空缺,普通话资料越来越少的可怜,所以开端的时候一只雾水(即使从前用过工作流,不过感觉距离非常多),并且官方的手册还不是很周密;所以本人把本人在上学应用的进程遭遇的有个别难题都位列出来分享给我们;以下几点是本身遇见和想到的,要是您还会有何疑难能够在评价三月本人沟通再补偿。

2.第一使用境遇难点访问

因为Activiti刚刚退出不久所以资料比较空缺,普通话资料越来越少的可怜,所以起首的时候一只雾水(即使以前用过工作流,可是感到距离比较多),并且官方的手册还不是很完善;所以笔者把自己在上学应用的进度遭逢的一对疑惑都位列出来分享给我们;以下几点是本身遇上和想到的,假若你还会有怎么着疑难能够在评价夹钟自个儿沟通再补充。

一. 借款人信用卡音讯修改

2.1 陈设流程图后普通话乱码

乱码是一直缠绕着国人的主题材料,在此以前各样技艺、工具出现乱码的标题写过无数篇章,这里也不例外……,Activiti的乱码难题在流程图中。

流程图的乱码如下图所示:

图片 3

化解办法有二种:

2.1 安顿流程图后汉语乱码

乱码是直接缠绕着国人的标题,以前各个本领、工具出现乱码的难题写过不菲稿子,这里也不例外……,Activiti的乱码难点在流程图中。

流程图的乱码如下图所示:

图片 4

消除办法有三种:

该流程发起原因首假若出于借款人信用卡转移原因须要修改. 流程关键步骤为:

2.1.1 修改源代码方式

修改源码

org.activiti.engine.impl.bpmn.diagram.ProcessDiagramCanvas

在构造方法

public ProcessDiagramCanvas(int width, int height)

中有一行代码是设置字体的,默许是用 Arial 字体,那便是乱码产生的原故,把字改为本地的普通话字体就能够,举个例子:

Font font = new Font("WenQuanYi Micro Hei", Font.BOLD, 11);

本来假设你有安插文件读取工具那么能够设置在*.properties文件中,笔者便是如此做的:

Font font = new Font(PropertyFileUtil.get("activiti.diagram.canvas.font"), Font.BOLD, 11);

2.1.1 修改源代码方式

修改源码

org.activiti.engine.impl.bpmn.diagram.ProcessDiagramCanvas

在构造方法

public ProcessDiagramCanvas(int width, int height)

中有一行代码是安装字体的,默许是用Arial字体,这正是乱码发生的来头,把字改为地面包车型地铁普通话字体就可以,比如:

?

1
Font
font =
new
Font(
"WenQuanYi
Micro Hei"
,
Font.BOLD,
11);

自然假诺您有安排文件读取工具那么能够安装在*.properties文件中,笔者正是这么做的:

?

1
Font
font =
new
Font(PropertyFileUtil.get(
"activiti.diagram.canvas.font"),
Font.BOLD,
11);

5.12本子最先扶助设置字体名称,在斯特林发动机中增添如下设置,在生成图片时就可以使用微软雅黑设置图片中的文字。

?

1
<property
name
="activityFontName"
value
="微软雅黑"></property>

❶ 客户联系客商服务人士,提交报名, 包含借款音讯, 手持身份ID照片,
信用卡音信等

2.1.2 使用压缩包格局地署

Activiti接济安顿*.bpmn20.xml、bar、zip格式的流程定义。

选用Activit Deisigner工具设计流程图的时候会有八个类其他文件:

  • .activiti设计工具使用的公文

  • .bpmn20.xml企划工具自动遵照.activiti文件生成的xml文件

  • .png流程图图片

化解办法正是把xml文件和图表文件同有的时候候陈设,因为在单独安插xml文件的时候Activiti会自动生成一张流程图的图样文件,不过如此在动用的时候坐标和图表对应不起来……

故而把xml和图表同临时候布署的时候Activiti自动关联xml和图表,当要求获得图片的时候一向回到安插时压缩包里面包车型大巴图片文件,并不是Activiti自动生成的图纸文件

2.1.2 使用压缩包格局地署

Activiti帮助安插*.bpmn20.xml、bar、zip格式的流水生产线定义。

使用Activit Deisigner工具设计流程图的时候会有三个类其他文本:

  • .activiti设计工具使用的文件

  • .bpmn20.xml统一打算工具自动依照.activiti文件生成的xml文件

  • .png流程图图片

化解办法正是把xml文件和图片文件同偶然间铺排,因为在独立布置xml文件的时候Activiti会自动生成一张流程图的图纸文件,不过如此在采纳的时候坐标和图片对应不起来……

故而把xml和图表同时安插的时候Activiti自动关联xml和图片,当要求取得图片的时候一向回到安排时压缩包里面包车型地铁图纸文件,并不是Activiti自动生成的图形文件

❷ 申请提交系统后, 由风控进行甄别

2.1.2.1 使用工具打包Bar文件

右键项目名称然后点击“Create deployment
artifacts”,会在src目录中创制deployment文本夹,里面含有*.bar文件.

2.1.2.1 使用工具打包Bar文件

在“Package Explorer”视图中右键项目名称然后点击“Create deployment
artifacts”,会在src目录中开创deployment文件夹,里面包括*.bar文件.

❸ 运维单位开展改换操

2.1.2.2 使用Ant脚本打包Zip文件

那也是大家运用的办法,你能够手动选项xml和png打包成zip格式的文件,也能够像大家同样采取ant
target的主意打包那多少个文本。

<?xml version="1.0" encoding="UTF-8"?>
<project name="foo">

    <property name="workflow.definition" value="foo-common-core/src/main/resources/diagrams" />
    <property name="workflow.deployments" value="foo-common-core/src/main/resources/deployments" />

<target name="workflow.package.oa.leave">
        <echo>打包流程定义及流程图::OA-请假</echo>
        <zip destfile="${workflow.deployments}/oa/leave.zip" basedir="${workflow.definition}/oa/leave" update="true"
            includes="*.xml,*.png" />
    </target>
</project>

诸如此比当修改流程定义文件后假设运营ant命令就足以打包了:

ant workflow.package.oa.leave

今后配置bar恐怕zip文件查看流程图图片就不是乱码了,而是你的压缩包里面包车型大巴png文件。

2.1.2.2 使用Ant脚本打包Zip文件

那也是咱们运用的艺术,你能够手动选项xml和png打包成zip格式的文书,也能够像大家同样使用ant
target的方法打包那五个文本。

123456789101112
<?xml version="1.0" encoding="UTF-8"?><project name="foo">     <property name="workflow.definition" value="foo-common-core/src/main/resources/diagrams" />    <property name="workflow.deployments" value="foo-common-core/src/main/resources/deployments" /> <target name="workflow.package.oa.leave">     <echo>打包流程定义及流程图::OA-请假</echo>        <zip destfile="${workflow.deployments}/oa/leave.zip" basedir="${workflow.definition}/oa/leave" update="true"            includes="*.xml,*.png" /> </target></project>

view
rawbuild.xml hosted
with ❤ by GitHub

诸有此类当修改流程定义文件后只要运转ant命令就足以打包了:

ant workflow.package.oa.leave

以后安排bar可能zip文件查看流程图图片就不是乱码了,而是你的压缩包里面包车型地铁png文件。

二. 提前还款流程

2.2 使用引擎提供的Form如故自定义业务Form

2.2 使用引擎提供的Form照旧自定义业务Form

倡导流程的关键缘由是顾客期待遵照公约进行提前还款. 流程关键步骤为:

2.2.1 引擎提供的Form

概念表单的主目的在于各类Task标签中定义extensionElementsactiviti:formProperty就可以,达到这一个节点的时候能够经过API读取表单成分。

Activiti官方的例子使用的正是在工艺流程定义中设置每贰个节点展现怎么的表单哪些字段必要展现、哪些字段只读、哪些字段必填。

唯独这种办法唯有适用于比较轻巧的流程,对于有个别复杂可能页面须要工作逻辑的剖断的情状就不适用了。

对于数据的保留都以在外燃机的表中,不低价和其余表的关系、对任何系统的布置性也不利于!

2.2.1 引擎提供的Form

概念表单的艺术在各种Task标签中定义extensionElementsactiviti:formProperty就能够,到达那个节点的时候能够由此API读取表单成分。

Activiti官方的事例使用的正是在流水生产线定义中装置每一个节点显示怎么的表单哪些字段必要突显、哪些字段只读、哪些字段必填。

不过这种措施唯有适用于比较简单的流水生产线,对于某些复杂可能页面供给专门的学问逻辑的论断的景观就不适用了。

对于数据的保存都是在斯特林发动机的表中,不便于和任何表的涉嫌、对全数系统的设计也会有损!

❶ 借款人联系客服职员, 提交报名

2.2.2 自定义业务Form

这种艺术应该是豪门用的最多的了,因为平常的工作系统职业逻辑都会比较复杂,并且数据库台湾中国广播集团大表都会有依据关系,表单中有不胜枚举场合判定。

例如大家的系统适用jQuery
UI作为UI,有繁多javascript代码,页面包车型地铁成都百货上千操作要求极其管理(比如:多少个选择的排外、每一种节点遵照项目和操作人展现不一致的开关);基本每一个集团都有一套本身的UI风格,要保险五个种类的操作习于旧贯一致只可以选用自定义表单技能满足。

2.2.2 自定义业务Form

这种艺术应该是豪门用的最多的了,因为相似的事务系统业务逻辑都会比较复杂,並且数据库中相当多表都会有依赖关系,表单中有众多景况决断。

举个例子我们的系统适用jQuery
UI作为UI,有成都百货上千javascript代码,页面包车型客车广大操作须要新鲜管理(比方:八个选取的排外、每一种节点根据项目和操作人展现不一致的开关);基本每种公司都有一套自个儿的UI风格,要保险多少个种类的操作习贯一致只可以动用自定义表单才干满意。

❷ 运维生成提前还款表达书, 其包涵详细金额多少

2.3 业务和流程的涉及形式

本条标题在群里面很三个人都问过,那也是本人刚刚起首吸引的地点;

新兴看了以下API开采RuntimeService有五个办法:

2.3 业务和流程的关系格局

那个标题在群里面相当多少人都问过,那也是自己刚刚开首吸引的地点;

后来看了以下API开采RuntimeService有七个点子:

❸ 借款人确认, 通过客服服务人口上传签名照片

2.3.1 startProcessInstanceByKey

javadoc对其认证:

startProcessInstanceByKey(String processDefinitionKey, Map variabes) 
          Starts a new process instance in the latest version of the process definition with the given key

 

其中businessKey正是事情ID,举个例子要提请请假,那么先填写登记新闻,然后(保存+运行流程),因为请假是单身设计的数据表,所以保存后获得实体ID就足以把它传给processInstanceBusinessKey方法运行流程。当须要依靠businessKey查询流程的时候就足以经过API查询:

runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(processInstanceBusinessKey, processDefinitionKey);

 

议数据库冗余设计:在业务表设计的时候增多一列:PROCESS_INSTANCE_ID varchar2(64),在流水线运维之后把流程ID更新到业务表中,那样无论从业务只怕流程都足以查询到对方!

非常表达: 此方法运维时自动选用新型版本的流水线定义。

2.3.1 startProcessInstanceByKey

javadoc对其认证:

startProcessInstanceByKey(String processDefinitionKey, Map variables) 
          Starts a new process instance in the latest version of the process definition with the given key

其中businessKey便是业务ID,举例要提请请假,那么先填写登记消息,然后(保存+运维流程),因为请假是独自设计的数据表,所以保存后得到实体ID就能够把它传给processInstanceBusinessKey格局运维流程。当需求基于businessKey查询流程的时候就能够透过API查询:

?

1
runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(processInstanceBusinessKey,
processDefinitionKey)

建议数据库冗余设计:在业务表设计的时候增加一列:PROCESS_INSTANCE_ID
varchar2(64)
,在工艺流程运转以往把流程ID更新到工作表中,那样不管从事情依然流程都得以查询到对方!

特意表达: 此方法运行时自动选取新型版本的流程定义。

❹ 运维代扣还款金额, 结清借款

2.3.2 startProcessInstanceById

javadoc对其认证:

startProcessInstanceById(String processDefinitionId, String businessKey, Map variables) 
          Starts a new process instance in the exactly specified version of the process definition with the given id.

 

processDefinitionId:这几个参数的值能够经过repositoryService.createProcessDefinitionQuery()方法查询,对应数据库:ACT_RE_PROCDEF;每便安排三次流程定义就能够增加一条数据,同名的本子号加多。

特别表达: 此能够钦点差异版本的流水生产线定义,让客户多一层选取。

2.3.2 startProcessInstanceById

javadoc对其验明正身:

startProcessInstanceById(String processDefinitionId, String businessKey, Map variables) 
          Starts a new process instance in the exactly specified version of the process definition with the given id.

processDefinitionId:那一个参数的值能够经过repositoryService.createProcessDefinitionQuery()格局查询,对应数据库:ACT_RE_PROCDEF;每便铺排三回流程定义就能增多一条数据,同名的本子号增加。

极其说明: 此能够钦赐差别版本的流水生产线定义,让顾客多一层采纳。

❺ 生成还款结清评释

2.3.3 怎么着挑选

提出选取startProcessInstanceByKey,特殊境况须求动用过去的本子接纳接纳startProcessInstanceById

2.3.3 怎么着采取

提出利用startProcessInstanceByKey,特殊景况须求采用过去的本子接纳使用startProcessInstanceById

在凉台的其实运维中, 有三种种种的事体需求管理, 包括借款人, 出借人,
资金等等, 同期还涉及到各类区别的业务部门,
並且流程的流转操作职员和单位也乘机企务的进化而各异的调解.
设计二个基础的流程框架和兑现基础代码, 变成轻易的支出格局是该体系的要害.
因而总种类统的安插性涉及到以下着重多少个地点:

2.4 同步客户数据

以此标题也是比较多的人询问过,Activiti补助对职分分配到:钦点人、内定组、两个结合,而那些人和组的信息都保存在ACT_ID..表中,有和煦的客户和组(剧中人物)处理让广大人仓惶了;原因是因为每种系统都会设有一个权力管理模块(维护:顾客、部门、角色、授权),不知道该怎么和Activiti同步。

2.4 同步顾客数量

本条主题素材也是非常多的人询问过,Activiti援救对职责分配到:钦赐人、钦定组、两个结合,而那么些人和组的音讯都保存在ACT_ID..表中,有和好的顾客和组(角色)管理让洋外国人仓皇了;原因是因为各种系统都会存在贰个权力管理模块(维护:客商、部门、剧中人物、授权),不明了该怎么和Activiti同步。

☞ 采纳适宜的干活流引擎

2.4.1 提出管理方式

Activiti有一个IdentityService接口,通过这几个接口能够操控Activiti的ACT_ID_*表的多寡,平时的做法是用工作种类的权位管理模块维护客商数据,当举办CRUD操作的时候在原有专门的工作逻辑后边增加同步到Activiti的代码;举例增添多个顾客时同步Activiti
User的代码片段:

/**
 * 保存用户信息 并且同步用户信息到activiti的identity.User,同时设置角色
 * @param user
 * @param roleIds
 */
public void saveUser(User user, List<Long> roleIds, boolean synToActiviti) {
    accountManager.saveEntity(user);
    String userId = user.getId().toString();

    if (synToActiviti) {
        List<org.activiti.engine.identity.User> activitiUsers = identityService.createUserQuery().userId(userId).list();
        if (activitiUsers.size() == 1) {
            //更新信息
            org.activiti.engine.identity.User activitiUser = activitiUsers.get(0);
            activitiUser.setFirstName(user.getName());
            activitiUser.setLastName("");
            activitiUser.setPassword(user.getPassword());
            activitiUser.setEmail(user.getEmail());
            identityService.saveUser(activitiUser);

            // 删除用户的membership
            List<Group> activitiGroups = identityService.createGroupQuery().groupMember(userId).list();
            for (Group group : activitiGroups) {
                identityService.deleteMembership(userId, group.getId());
            }

            // 添加membership
            for (Long roleId : roleIds) {
                Role role = roleManager.getEntity(roleId);
                identityService.createMembership(userId, role.getEnName());
            }

        } else {
            org.activiti.engine.identity.User newUser = identityService.newUser(userId);
            newUser.setFirstName(user.getName());
            newUser.setLastName("");
            newUser.setPassword(user.getPassword());
            newUser.setEmail(user.getEmail());
            identityService.saveUser(newUser);

            // 添加membership
            for (Long roleId : roleIds) {
                Role role = roleManager.getEntity(roleId);
                identityService.createMembership(userId, role.getEnName());
            }
        }
    }

}

 

除去操作也和这一个就如!

不论是从作业种类有限支撑顾客仍然从Activiti维护,确定要规定一方,然后CRUD的时候一齐到对方,固然急需一块三个子系统那么能够再调用WebService实现。

2.4.1 提议管理格局

Activiti有一个IdentityService接口,通过那一个接口能够操控Activiti的ACT_ID_*表的数量,日常的做法是用专门的事业系统的权能管理模块维护客商数据,当实行CRUD操作的时候在原来专门的职业逻辑后边加多同步到Activiti的代码;比方增多一个客商时同步Activiti
User的代码片段:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
/** * 保存用户信息 并且同步用户信息到activiti的identity.User,同时设置角色 * @param user * @param roleIds */public void saveUser(User user, List<Long> roleIds, boolean synToActiviti) { accountManager.saveEntity(user); String userId = user.getId().toString();   if (synToActiviti) {      List<org.activiti.engine.identity.User> activitiUsers = identityService.createUserQuery().userId(userId).list();       if (activitiUsers.size() == 1) {          //更新信息         org.activiti.engine.identity.User activitiUser = activitiUsers.get(0);          activitiUser.setFirstName(user.getName());           activitiUser.setLastName("");          activitiUser.setPassword(user.getPassword());            activitiUser.setEmail(user.getEmail());          identityService.saveUser(activitiUser);             // 删除用户的membership          List<Group> activitiGroups = identityService.createGroupQuery().groupMember(userId).list();            for (Group group : activitiGroups) {                identityService.deleteMembership(userId, group.getId());          }            // 添加membership          for (Long roleId : roleIds) {               Role role = roleManager.getEntity(roleId);                identityService.createMembership(userId, role.getEnName());           }        } else {         org.activiti.engine.identity.User newUser = identityService.newUser(userId);          newUser.setFirstName(user.getName());            newUser.setLastName("");           newUser.setPassword(user.getPassword());         newUser.setEmail(user.getEmail());           identityService.saveUser(newUser);          // 添加membership          for (Long roleId : roleIds) {               Role role = roleManager.getEntity(roleId);                identityService.createMembership(userId, role.getEnName());           }        }    } }

view
rawAccountServiceImpl.java hosted
with ❤ by GitHub

剔除操作也和那么些就像!

任凭从专门的学业系统爱惜客户还是从Activiti维护,鲜明要明确一方,然后CRUD的时候共同到对方,假诺须求联合多少个子系统那么能够再调用WebService达成。

对于一个近似涉及到审查批准以及施行实际作业的体系, 基于轻易的境况调节的规划,
也许机关开拓类工作流引擎轮子的做法都以不合适.
所以八个开源何况被普及利用的行事流引擎是叁个不容置疑何况必需的选取. Activiti
职业流引擎由于其轻量级, 易用性等优点近年来在产业界被大面积使用.
其专业流的状态机和外界系统的接连只要求通过七个ID进行关联就能够,
即activiti的business key. (如下图)

2.5 流程图设计工具用什么样

Activiti提供了多个流程设计工具,不过面向对象差异。

  • Activiti
    Modeler,面向业务职员,使用开源的BPMN设计工具Signavio,使用BPMN描述业务流程图

  • Eclipse
    Designer,面向开拓职员,Eclipse的插件,能够让开荒职员定制种种节点的性质(ID、Name、Listener、Attr等)

2.5 流程图设计工具用哪些

Activiti提供了三个流程设计工具,可是面向对象不一样。

  • Activiti
    Modeler,面向业务人士,使用开源的BPMN设计工具Signavio,使用BPMN描述业务流程图

  • Eclipse
    Designer,面向开辟职员,Eclipse的插件,可以让开采人士定制种种节点的性质(ID、Name、Listener、Attr等)

图片 5

2.5.1 我们的格局

兴许你会奇异,因为大家平昔不应用Activiti
Modeler,大家感觉用Viso已经能公布流程图的意味了,并且项目首席营业官也是手艺出身,和开拓人士也便于调换。

当前以此连串是首先个使用Activiti的,初叶大家在须要调查切磋阶段选择Viso设计流程图,利用泳道流程图规划和客商联系,鲜明后由担负流程的开垦职员用Eclipse
Designer设计赢得bpmn20.xml,最终安插。

2.5.1 我们的艺术

兴许你会奇异,因为我们尚无行使Activiti
Modeler,我们认为用Viso已经能表达流程图的情致了,何况项目CEO也是本事出身,和开荒职员也轻易调换。

当下以此项目是第1个利用Activiti的,开端大家在须求应用切磋阶段采纳Viso设计流程图,利用泳道流程图规划和顾客调换,显著后由担当流程的开荒职员用Eclipse
Designer设计赢得bpmn20.xml,最后安顿。

☞设计通用的底层数据来支撑区别的职业

2.6 Eclipse Designer存在的主题素材

以此插件有三个很讨厌的Bug平素未修复,安装了插件后Eclipse的复制和粘帖火速键会被退换为(Ctrl+Insert、Shift+Insert);Bug描述请见:

  • Activit
    Forums中报告的Bug

  • Jira的登记

为此最后我们不得不单独开贰个安装了Eclipse
Designer的Eclipse特意用来布署流程图,那样就不影响健康使用Eclipse
JAVAEE了。

2.6 Eclipse Designer存在的题目

本条插件有一个很反感的Bug一向未修复,安装了插件后Eclipse的复制和粘帖飞速键会被调换为(Ctrl+Insert、Shift+Insert);Bug描述请见:

  • Activit
    Forums中告诉的Bug

  • Jira的登记

故此最后我们只能单独开三个装置了Eclipse
Designer的Eclipse特地用来安排流程图,这样就不影响健康使用Eclipse
JAVAEE了。

是因为那样三个运维管理体系涉及到各类不一致的事务数据.
如借款人新闻有关涉嫌借款ID, 银行卡音讯等; 如出借人消息则涉嫌客户ID,
电话号码等; 而对此资本有关如提前还款则涉及到提前还款日期, 还款金额等.
所以一套支撑不一样实际业务的流水生产线数据表结构也是不行主要.

3.配置

3.配置

☞ 基础框架代码的陈设性

3.1 集成Spring

对此和Spring的集成Activiti做的不利,不难布置部分Bean代理就能够兑现,但是有八个和业务相关的地点要唤醒:

  • 配置processEngineConfiguration的时候属性transactionManager要接纳和事务职能的同叁个事务管理Bean,不然事务差异步。

  • 对此贯彻了org.activiti.engine.delegate包中的接口的类须要被专门的学问调控的贯彻类供给被Spring代理,并且拉长事务的Annotation大概在xml中安插,比如:

    /**
     * 创建缴费流程的时候自动创建实体
     *
     * @author HenryYan
     */
    @Service
    @Transactional
    publicclass CreatePaymentProcessListener implementsExecutionListener {
       ....
    }
    

?

3.1 集成Spring

对此和Spring的集成Activiti做的没有错,轻松布署部分Bean代理就能够落成,然而有多个和专业相关的位置要提示:

  • 配置processEngineConfiguration的时候属性transactionManager要选择和工作功用的同一个事务管理Bean,不然事务分歧台。

  • 对于实现了org.activiti.engine.delegate包中的接口的类需求被专业调控的落到实处类须要被Spring代理,並且拉长事务的Annotation或然在xml中配置,比方:

?

1
2
3
4
5
6
7
8
9
10
/**
 *
创建缴费流程的时候自动创建实体
 *
 *
@author HenryYan
 */
@Service
@Transactional
public
class

CreatePaymentProcessListener
implements
ExecutionListener {
   ....
}

二个好的设计不是一步到位的设计,
而是二个规行矩步的历程以及持续重构的进程.
不过丰富首要的少数就是在一初叶能够基于当下的需要以及所能预感的要求举办规划,
而且在这几个基础框架代码上开荒要更为便于和简洁.

4.施用单元测量检验

单元测量检验均使用Spring的AbstractTransactionalJUnit4SpringContextTests作为SuperClass,并且在测验类增添:

@ContextConfiguration(locations = { "/applicationContext-test.xml"})
@RunWith(SpringJUnit4ClassRunner.class)

?

即便Activiti也提供了测量试验的一部分超类,可是认为倒霉用,所以自个儿包装了一部分方法。

代码请转移:

4.接纳单元测量检验

单元测量检验均使用Spring的AbstractTransactionalJUnit4SpringContextTests作为SuperClass,何况在测验类增加:

?

1
2
@ContextConfiguration(locations
= {
"/applicationContext-test.xml"
})
@RunWith(SpringJUnit4ClassRunner.class)

固然如此Activiti也提供了测量检验的部分超类,然而以为倒霉用,所以自身包装了一些格局。

代码请转移:

◆✦以下对第二、三点开展进行✦◆

4.1 验证流程图设计是不是准确

代码请转移:

4.1 验证流程图设计是或不是正确

代码请转移:

图片 6

4.2 业务对象和流程关联测量检验

代码请转移:

4.2 业务对象和流程关联测验

代码请转移:

数据库设计

5.各个气象的职务查询以及和事情对象关联

我们当前分为4中状态:未签收、办理中、运维中、已产生。

询问到职务依然流程实例后要来得在页面,这一年必要充足业务数据,最后结果正是业务和流程的并集,请参照他事他说加以考察6.2

5.各个处境的职分查询以及和事务对象关系

咱俩眼下分为4中状态:未签收、办理中、运维中、已到位。

查询到职责照旧流程实例后要来得在页面,这年需求丰硕业务数据,最后结果正是职业和流程的并集,请参照他事他说加以考察6.2

如上所说, 那样的八个多少布置必得能够知足:

5.1 未签收(Task)

此类职责针对于把Task分配给一个剧中人物时,比如部门长官,因为机构CEO角色能够钦赐多个人所以需求先签收再办理,术语:抢占式

对应的API查询:

/**
 * 获取未签收的任务查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
publicTaskQuery createUnsignedTaskQuery(String userId) {
    TaskQuery taskCandidateUserQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey())
            .taskCandidateUser(userId);
    returntaskCandidateUserQuery;
}

?

5.1 未签收(Task)

此类职责针对于把Task分配给三个角色时,举例部门组长,因为机构官员剧中人物能够钦赐多少人所以供给先签收再办理,术语:抢占式

对应的API查询:

?

1
2
3
4
5
6
7
8
9
10
/**
 *
获取未签收的任务查询对象
 *
@param userId    用户ID
 */
@Transactional(readOnly
=
true)
public
TaskQuery createUnsignedTaskQuery(String userId) {
    TaskQuery
taskCandidateUserQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey())
            .taskCandidateUser(userId);
    return
taskCandidateUserQuery;
}
  1. 可知满意不一致的业务域的必要, 如出借, 借款, 资金有关的实际职业数据

  2. 能够记录每一步的操作审查批准或作业推行结果, 同一时候记录相关的数量快速照相

5.2 办理中(Task)

此类职务数据类源有三种:

  • 签收后的,5.第11中学签收后就应该为办理中状态

  • 节点钦命的是现实到壹位,并不是角色

对应的API查询:

/**
 * 获取正在处理的任务查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
publicTaskQuery createTodoTaskQuery(String userId) {
    TaskQuery taskAssigneeQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey()).taskAssignee(userId);
    returntaskAssigneeQuery;
}

?

5.2 办理中(Task)

该类义务数据类源有二种:

  • 签收后的,5.第11中学签收后就活该为办理中状态

  • 节点钦命的是具体到一人,并不是角色

对应的API查询:

?

1
2
3
4
5
6
7
8
9
/**
 *
获取正在处理的任务查询对象
 *
@param userId    用户ID
 */
@Transactional(readOnly
=
true)
public
TaskQuery createTodoTaskQuery(String userId) {
    TaskQuery
taskAssigneeQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey()).taskAssignee(userId);
    return
taskAssigneeQuery;
}

故而, 基于具体的职业进行数据表的准备是不确切的, 且不可能扩张.
常见的规划为依附Key-Value的统一筹算,
而key则是逐个不一致专门的学问系统关系到的metadata. 如USEEvoque_ID(用户ID),
LOAN_ID(借款ID)等等. 设计概述如下:

5.3 运行中(ProcessInstance)

简易正是没有达成的流程,全数加入过的人都应有能够见见这几个实例,不过Activiti的API未有得以经过顾客查询的措施,那么些只好和睦用hack的艺术管理了,作者当下还一贯不管理。

从表ACT_RU_EXECUTION中查询数据。

对应的API查询:

/**
 * 获取未经完成的流程实例查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
publicProcessInstanceQuery createUnFinishedProcessInstanceQuery(String userId) {
    ProcessInstanceQuery unfinishedQuery = runtimeService.createProcessInstanceQuery().processDefinitionKey(getProcessDefKey())
            .active();
    returnunfinishedQuery;
}

?

5.3 运行中(ProcessInstance)

回顾便是从未停止的流程,全体出席过的人都应该能够看来那几个实例,不过Activiti的API未有得以经过顾客查询的不二等秘书技,那一个只好和睦用hack的形式处理了,笔者当下还尚未拍卖。

从表ACT_RU_EXECUTION中询问数据。

对应的API查询:

?

1
2
3
4
5
6
7
8
9
10
/**
 *
获取未经完成的流程实例查询对象
 *
@param userId    用户ID
 */
@Transactional(readOnly
=
true)
public
ProcessInstanceQuery createUnFinishedProcessInstanceQuery(String userId) {
    ProcessInstanceQuery
unfinishedQuery = runtimeService.createProcessInstanceQuery().processDefinitionKey(getProcessDefKey())
            .active();
    return
unfinishedQuery;
}

图片 7

5.4 已完成(HistoricProcessInstance)

现已截至的流程实例。

从表ACT_HI_PROCINST中询问数据。

/**
 * 获取已经完成的流程实例查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
publicHistoricProcessInstanceQuery createFinishedProcessInstanceQuery(String userId) {
    HistoricProcessInstanceQuery finishedQuery = historyService.createHistoricProcessInstanceQuery()
            .processDefinitionKey(getProcessDefKey()).finished();
    returnfinishedQuery;
}

 

?

5.4 已完成(HistoricProcessInstance)

早就告竣的流程实例。

从表ACT_HI_PROCINST中询问数据。

?

1
2
3
4
5
6
7
8
9
10
/**
 *
获取已经完成的流程实例查询对象
 *
@param userId    用户ID
 */
@Transactional(readOnly
=
true)
public
HistoricProcessInstanceQuery createFinishedProcessInstanceQuery(String userId) {
    HistoricProcessInstanceQuery
finishedQuery = historyService.createHistoricProcessInstanceQuery()
            .processDefinitionKey(getProcessDefKey()).finished();
    return
finishedQuery;
}

叁个Request代表某一位发起的央浼, Snapshot代表那一个流程的每一步操作.
Property则分别为Request的Snapshot的实际的多少,
当其REQUEST_ID非空SNAPSHOT_ID为空时表示其为REQUEST的习性(SNAPSHOT同理),
即客户发起呼吁所引导的数据. 如: 客户音信修改:
PROPERTY则囊括NAME(KEY)为USEENVISION_ID(客户独一ID),
ATTACHMENT(客商手持身份ID照片), EMAIL(修改项)等相应的值. 而对于SNAPSHOT,
则记录对应调查以及操作的音讯,
其相应的PROPERTY则保留了对有些数据修改前后的值.

5.5 查询时和作业涉及

升迁:在此之前在业务对象增加了PROCESS_INSTANCE_ID字段

思路:今后能够动用那一个字段查询了,不管是Task照旧ProcessInstance都能够获得流程实例ID,能够依照流程实例ID查询实体然后把流程对象设置到实体的二个属性中由Action可能Controller输出到前台。

代码请参见:

5.5 查询时和业务涉及

升迁:在此以前在业务对象增多了PROCESS_INSTANCE_ID字段

思路:现在能够动用这几个字段查询了,不管是Task照旧ProcessInstance都能够取得流程实例ID,可以依据流程实例ID查询实体然后把流程对象设置到实体的贰个属性中由Action或许Controller输出到前台。

代码请仿效:

基本功框架代码设计

6.UI及截图

结合实际业务描述四个业务从最早到结束的进度,对于迷惑的同班看完峰回路转了;这里运用请假作为例子。

6.UI及截图

结合实际业务描述一个业务从初步到停止的经过,对于吸引的同窗看完茅塞顿开了;这里运用请假作为例子。

初叶的景色和需求包括:

6.1 单独一个列表负担申请

那般的裨益是申请和流程办理分离开管理,列表突显未运行流程的请假记录(数据库PROCESS_INSTANCE_ID为空)。

报名分界面包车型地铁截图:

图片 8

6.1 单唯三个列表肩负申请

如此这般的实惠是报名和流程办理分离开管理,列表显示未运行流程的请假记录(数据库PROCESS_INSTANCE_ID为空)。

报名分界面包车型客车截图:

图片 9

  1. 一些通用的activiti流程,
    如一步操作即开立后只必要一步成功操作, 两步流程 –
    创制后一步检查核对一步操作等, 不一致的作业会利用同一的流程.

  2. 在activiti流程一样的情状下,
    分化的政工的步子其管理人/组则差异

  3. 不等业务流程的莫过于代码开采相应简洁,
    和工作流引擎解耦, 即实际的开 发人员在不打听办事流引擎具体做事原理的图景下能够张开快速的付出, 并
    只须求关注具体 的作业要求

6.2 流程状态

图片 10

6.2 流程状态

图片 11

为了消除#1的主题材料,
则要求定义出流程–步骤—业务(央浼类型)—管理人/组 的安插 关系,
并在工艺流程流转时自动安装, 实际不是在流水生产线描述文件 (bpmn)里 钦命

6.3 流程追踪

图表格局展现当前节点:

图片 12

列表格局显得流程流转进程:

图片 13

6.3 流程追踪

图表方式呈现当前节点:

图片 14

列表方式体现流程流转进度:

图片 15

为了化解 #2 的标题,
则必要用服务扩充打包, 抽象出一些接口以及基类的实 现, 并
应用有的宽广的设计情势(工厂格局)和java的特征(反射).

6.3.1 当前节点定位JS

Java代码请移步:

Javascript思路:先经过Ajax获取当前节点的坐标,在内定位置增添碧绿边框,然后加载图片。

代码移步:

6.3.1 当前节点定位JS

Java代码请移步:

Javascript思路:先经过Ajax获取当前节点的坐标,在钦赐地点增添石绿边框,然后加载图片。

代码移步:

下图为主干的架构设计

7.开启Logger

  1. 添加log4j的jar
  2. 设置log4j.logger.java.sql=DEBUG

7.开启Logger

  1. 添加log4j的jar
  2. 设置log4j.logger.java.sql=DEBUG

图片 16

8.结束

前边就想写那篇小说,今后总算实现了,开支了几个时辰,希望能节约你几天的时光。

请读者稳重阅读Activiti的客商手册和Javadoc。

来自:

8.结束

后面就想写那篇文章,未来好不轻易完毕了,开销了几个刻钟,希望能节约你几天的时日。

请读者留意阅读Activiti的顾客手册和Javadoc。

举例有怎么样疑难照旧对于效率的落到实处有越来越好的不二诀要应接建议、分享。

听别人讲那样的框架造成基础代码后,
最后对于贰个兑现具体作业的开垦职员来讲, 其落成贰个业务流程代码首要不外乎:

9.动态内定义务办理人

  1. 兑现贰个创办Request的页面,
    用于录入专门的学问数据

  2. 完毕叁个Request详细页面, 用于显示详情,
    包涵操作历史, 和作业操作按键

9.1 手动设置任务办理人

?

1
<usertask
id
="hrAudit"
name
="人事审批"
activiti:assignee
="${hrUserId}"></usertask>

动态钦定职务办理人是群里面询问比较多的主题材料之一,其实就是一层窗户纸,只要在职责成功的时候传递activiti:assignee属性中的变量就可以。


Map<String, Object> variables = new HashMap<String,
Object>();

variables.put(“hrUserId”, hrUserId);

taskService.complete(taskId, variables);


3.
落实该事情涉嫌的具体步骤的操作processor类(如审查批准或和任何系统接入,
完结实际的业务),

9.2 自动安装职责办理人

上面包车型客车代码是应用initiator功效,设置三个名号(不是变量而是变量名)到起步事件上,况兼在开行流程时调用一些底下的办法:

?

1
identityService.setAuthenticatedUserId(currentUserId);

当中currentUserId表示近些日子客商,也正是运营流程的人,配置如下所示:

?

1
2
<startevent
id
="startevent1"
name
="Start"
activiti:initiator
="applyUserId"></startevent>
<usertask
id
="reportBack"
name
="销假"
activiti:assignee
="${applyUserId}"></usertask>

那般流程运转之后假如义务流转至”销毁假冒货物”节点则会自动把职责分配给运转流程的人。

  1. 将流程涉及的processor和相应的业务种类,
    流程名, 流程步骤实行挂号绑定

9.3 获取流程发起人

假诺在开发银行流程的时候调用了下边包车型客车代码:

?

1
identityService.setAuthenticatedUserId(currentUserId);

引擎会记录启迷人,即在ACT_HI_PROINST表的START_USER_ID字段,能够通过上边包车型客车代码获取。

?

1
2
HistoricProcessInstance
hi = historyService.createHistoricProcessInstanceQuery().singleResult();
hi.getStartUserId();

变异历程

10. 职务代办

重重人问“Owner”属性为啥是空的,曾几何时用?要询问它的效果与利益首先要询问“代办”。

代办的概念能够用上边包车型地铁一句话总结:

你领导接到一个任务,让你代办,你办理完成后任务还是回归到你的领导,事情是你做的,功劳是你领导的,此乃代办也!

总的来看那些单元测量检验你就精通怎么是代办:ProcessTestDelegateTask

最好把activiti-study其一类型下载下来导入到Eclipse中运维一下:

原创文章,转发请注脚:转载自:办事流引擎Activiti使用总括

正如上面曾提起, 对于一个系统规划, 不容许一步到位,
在最先时要引发最急需减轻的主题材料, 比方在那个系统开首阶段,
最宗旨的计划性包涵:

➤ 数据库设计 和Request瑟维斯对底层数据操作的卷入

➤ WorkflowService对职业流引擎的包装

➤可配置化的依赖作业品种(Request Type)
和配备(process_cfg)在运维时动态设置流程相应的管理人/组

不停的重构包罗:

➤将各样管理类(业务管理类, 流程管理人/组分配管理类, 通告管理类)
通过RegisterService的会晤登记管理,
并且援救选取对于特定的流水生产线完结特定的拍卖类来代替暗中认可的管理类

➤RequestQuery协助统一的查询入口对业务流程数据开展询问

➤ 遵照作业须求提供ASync的processor管理基类, 因为实际利用中窥见,
一些事务的管理(如批量)须要一段时间的施行技艺到位,
而异步管理基类则成功基础完毕, 并由相应子类去落到实处虚函数就可以.

公共化专门的学问流模块:

➤ 这段日子, 其余一个类型其应用到的情景和这么些种类有类似之处,
其独立于该业务管理平台. 在这种情景下, 将该职业流相关的模块进行公共化,
以JAEnclave包的样式提供, 使得别的三个系统的开销能够短时间内完结平等的机能

借鉴Activiti的源代码

在打算和兑现该系统时会有

那样可能那样的迷离大概斗争,

哪个种类完结越来越好?

人家的种类是怎样落到实处的?

这里举多少个例子

Property表里是否须要须求用不相同的字段(LONG_VALUE,
TEXT_VALUE, DOUBLE_VALUE等)存区别类其余值;依然一向都存成字符串,
在代码中再依照需求转成Long, Double等?当然两种落成都以一蹴而就的,
并且各有利害,
而且个人感觉存在区别的字段上亮点更加大一些(首要反映在查询功能),
不过何等越来越让本身信服?
在看activiti的文书档案时意识外界的作业数据以Map的法子存在activiti的数据库中,
那么activiti的设计者一样会遇到一样的标题.
通过查看源代码以及其数据库设计, 开采其将数据存入分歧的字段.
不过在自个儿的宏图中, 笔者并未完全照搬Activiti的管理格局, 比如:
笔者并未有为布尔类型加单独的字段,
而是以0大概1的措施存入LONG_VALUE里。

Activiti中提供便捷的查询类, 如: ProcessInstanceQuery, TaskQuery.
其同期帮助依照Process和Task相应的属性数据进行查询,
和Request/Snapshot以及property有比相当大的相似之处,
借鉴并依赖真实情状贯彻团结的RequestQuery类, 援助各种复杂查询, 如:
遵照钦命的property的name和value查询, 帮忙or的查询等。

Activiti的数据库版本的机关晋级. 当我们进级activiti的本猪时,
其实大家只须要更新JAEvoque的版本号, 而不用关爱起底层数据库是还是不是须求升高,
activiti在其表中会记录数据库scheme的版本号,
运转时会自动判定并依据要求自动更新数据库. 那也是老大值得借鉴的地点,
越发是当以此模块被两个种类所运用时。

图片 17归来天涯论坛,查看越多

主编: