Commit e34d1fb8 authored by Jefferyne's avatar Jefferyne

Track 18 files into repository.

- untracked assets/act_vacationReq_bg_v.png
- untracked assets/act_vacationReq_ed.png
- untracked assets/act_vacationReq_exp.png
- untracked assets/act_vacationReq_exp_deal.png
- untracked assets/act_vacationReq_exp_start.png
- untracked assets/act_vacationReq_form.png
- untracked assets/approve_chain@2x.png
- untracked assets/approve_chain_entry.png
- untracked assets/custom-approve-action.png
- untracked assets/usertask-assignment.png
- untracked assets/wfl_user_task_approve.png
- modified codeStyle.md
- untracked 前端组件/hlsTextArea.md
- untracked 前端组件/hlsTlEdit.md
- untracked 后端开发/activiti-helper.md
- untracked 后端开发/activiti.md
- untracked 后端开发/activiti_editor_helper.md
- modified 后端开发/消息机制.md

Auto commit by GitBook Editor
parent 046bb554
...@@ -6,22 +6,42 @@ ...@@ -6,22 +6,42 @@
2. 提供他人使用的接口,原则上不允许修改**方法签名**,若是不再推荐使用,可以加**@ Deprecated**注解,同时提示新的接口名称。 2. 提供他人使用的接口,原则上不允许修改**方法签名**,若是不再推荐使用,可以加**@ Deprecated**注解,同时提示新的接口名称。
3. **DTO**类中所有的字段,不允许设置**默认值**,且DTO必须**重写toString()方法** 3. **DTO**类中所有的字段,不允许设置**默认值**,且DTO必须**重写toString()方法**
4. 原则上不允许使用递归,部分情况可以使用尾递归。 4. 原则上不允许使用递归,部分情况可以使用尾递归。
5. 代码中不允许出现魔法值,即未定义的任何常量。 错误的用法不限于以下形式: 5. 代码中不允许出现魔法值,即未定义的任何常量。错误的用法不限于以下形式:
```java ```java
if(user.getStatus() == 5){ if(user.getStatus() == 5){
// 5即为魔法值,应当避免使用 // 5即为魔法值,应当避免使用
// do something // do something
} }
// 推荐使用常量
private static final int EXPIRED_USER_STATUS = 5;
if(user.getStatus() == EXPIRED_USER_STATUS){
// do something
}
``` ```
6. 在类中定义的常量、变量及方法,需要严格控制访问修饰符,提供自己使用的设为private,可以供别人使用的可以设为public、protected等。 6. 在类中定义的常量、变量及方法,需要严格控制访问修饰符,提供自己使用的设为private,可以供别人使用的可以设为public、protected等。
7. 所有的覆写方法,必须加@Override注解,防止错误的拼写导致意外。 7. 所有的覆写方法,必须加**@Override**注解,防止错误的拼写导致意外。
8. Long类型的数据在初始化时必须使用大写的字母L, Double类型的数据必须使用大写的字母D。常见形式如
- **Long time=10000L**
- **Double money=12.3D**
9. 所有的数值的包装类型之间的比较不允许使用<>、==之类的简单运算符,需要使用equals方法或者compareTo方法。
10. 所有方法的引用类型参数,若是未添加**@NotNull**注解,必须先进行null判断。
11. 捕获异常一般不允许直接捕获基类Exception,也不可捕获异常后不进行处理。方法中也不可抛出基类Exception。
12. 部分异常若是上层(调用层)不能解决,则不允许抛出。最外层若是出现异常必须自行处理,不可将异常信息直接展示给用户。
13. 所有的日志信息**不允许使用System.out.println**输出,异常的日志信息使用**log.error**打印时,必须使用重载方法将捕获的异常作为第二个参数。如:
```java
try{
// throw some exceptions
}catch(IOException e){
logger.error(e.getMessage(), e);
}
```
--- --- --- ---
## 二、命名规范 ## 二、命名规范
1. 所有的命名不允许使用**拼音或者拼音英文混合**方式,但部分公认的拼音允许使用,如**shanghai,beijing**等。 1. 所有的命名不允许使用**拼音或者拼音英文混合**方式,但部分公认的拼音允许使用,如**shanghai,beijing**等。
2. 所有的命名不允许使用**下划线_**或者**美元符$**作为起始或者结束。错误的情况有不限于以下几种: 2. 所有的命名不允许使用**下划线`_`**或者**美元符`$`**作为起始或者结束。错误的情况有不限于以下几种:
- **_param** - **_param**
- **$param** - **$param**
- **param_** - **param_**
...@@ -29,7 +49,7 @@ if(user.getStatus() == 5){ ...@@ -29,7 +49,7 @@ if(user.getStatus() == 5){
- **_param$** - **_param$**
### 包命名规范 ### 包命名规范
1. 包名一般为域名倒叙开头,后接项目名,再加上单数形式的名词(项目中一般使用模块代码),且全部为小写字母,如: 1. 包名一般为域名倒序开头,后接项目名,再加上单数形式的名词(项目中一般使用模块代码),且全部为小写字母,如:
- 系统功能模块:**com.hand.hls.sys** - 系统功能模块:**com.hand.hls.sys**
- 合同功能模块:**com.hand.hls.cont** - 合同功能模块:**com.hand.hls.cont**
...@@ -38,7 +58,7 @@ if(user.getStatus() == 5){ ...@@ -38,7 +58,7 @@ if(user.getStatus() == 5){
- 存放该模块数据库实体对象: **dto** - 存放该模块数据库实体对象: **dto**
- 存放该模块的部分组件: **components** - 存放该模块的部分组件: **components**
- 存放该模块的业务接口: **service** - 存放该模块的业务接口: **service**
- 存放改模块的业务实现类: **service.impl** - 存放该模块的业务实现类: **service.impl**
- 存放该模块的Mybatis数据库交互层代码: **mapper** - 存放该模块的Mybatis数据库交互层代码: **mapper**
- 存放该模块的工具类代码: **utils** - 存放该模块的工具类代码: **utils**
- 存放自定义的异常类代码: **exception** - 存放自定义的异常类代码: **exception**
......
# hlsTextArea
文本框
##### xml配置
```xml
<!--h:为命名空间,必须要加的;hlsTextArea为组件名;id可写可不写-->
<h:hlsTextArea id="hlsTextArea"/>
```
| 属性 | 类型 | 说明 |
| -------- | -------- | -------- |
\ No newline at end of file
## TlEdit
多语言编辑
##### xml配置
```xml
<!--h:为命名空间,必须要加的;hlsTlEdit为组件名;id可写可不写-->
<h:hlsTlEdit id="hlsTlEdit"/>
```
#### **一般属性**
| 属性名 | 类型 |
| --- | --- |
| idField | String |
| field | String |
| dto | String |
| model | Function |
| open | Function |
| close | Function |
| placeholder | String |
| bind | Function |
用法示例:
```javascript
<h:hlsTlEdit id="tl" placeholder="多语言" bind="value:data.name" idField="id" field="name" dto="com.hand.hap.function.dto.Resource" model="viewModel.data">
</h:hlsTlEdit>
```
> **提示:**
>
> * 以上所有属性都直接可以添加到tlEdit标签上,用法皆为\[**属性名**\]="\[**属性值**\]"
# 工作流功能说明
---
### 1.流程设计
可以新建一个流程或者直接导入BPMN定义文件
融租易的环境有一些样例,可以下载学习。
以下截图以`请假流程`为例
使用activiti editor设计流程
![](/assets/act_vacationReq_ed.png)
如图点击编辑按钮会弹出流程设计器页面
![](/assets/act_vacationReq_exp.png)
> 左边有各种节点,事件等,可以拖拽到中间,右边是当前节点的属性烂
于常用节点,以及常用属性,参考[流程设计器简易教程](activiti_editor_helper.md)
### 2.流程部署
程设计好以后,点击流程设计页面操作栏的最后一个按钮(勾)即可发布流程
> 未发布过的流程或者改动过的流程,勾会以绿色展示,反之灰色
布以后可以在流程部署页面查看部署情况
> 如果有旧的流程启动了,发布的新版不会影响旧流程的运行
### 3.流程启动
际项目中需要客户化开发流程启动页面,参考`工作流测试`页面
作流测试页面可以动态解析`表单属性`,请假流程的启动页面如图所示
![](/assets/act_vacationReq_exp_start.png)
### 4.待办事项与历史流程
以在`我的待办`中查看当前登录用户(根据员工号)需要处理的待办事项
> 管理员可以在`待办事项中(管理员)`查看所有人的待办
待办页面点击办理,即可处理相应事项。
![](/assets/act_vacationReq_exp_deal.png)
上角的`审批动作`可以在通过在流程设计器里设置当前`人工任务`的表单属性动态生成,默认为
* 同意
* 拒绝
* 转交
> 对于activiti,审批动作仅仅是传回后台的值不一样
里的表单信息也需要需要客户化开发的,其实是一个iframe嵌套的页面,会在待办页面自动解析
> 页面路径在流程设计器里指定当前任务的`表单的标识Key`
demo放在`view/activiti/include`下
`历史流程`页面可以查看已经结束和正在运行的流程信息
## 审批链
---
功能入口是在 `流程设计` 界面。
<img width='460' src='/assets/approve_chain_entry.png'/>
点击 编辑图标 进入该流程的审批链配置界面
<img width='900' src='/assets/approve_chain@2x.png'/>
在这个编辑页面中,所有的 `UserTask` 节点会以 标签页的形式自动列出来。
切换标签页,下方表格中的数据会自动刷新为对应节点的数据。
上方的 操作按钮 是针对每个 标签页 操作的,并非针对整个页面。
主要属性说明:
* 名称
自定义,任意。`不允许重复`
节点原始名称 和 审批链的名称 拼接起来 作为运行时的名称。
* 审批人
内置 3 种
* 申请人(自己)
* 上级(申请人直接领导)
* 申请人部门领导
其他情况统统归为 `自定义表达式`
> 注意,这个功能要求流程的初始化器(Initiator)必须指定为 `initiator`
* 审批岗位
支持选择系统中的`岗位`,也支持自定义的`表达式`
> 目前在指定了审批人的情况下,再指定审批岗位是无效果的
* 表单
允许该轮次的审批显示指定的单据明细页面。
如果没有指定,则显示该节点原始设置的值。
* 顺序号
用来控制审批的先后 (目前尚不支持多人同时在同一轮次审批)
* 跳过条件
表达式,有值,且值为 true 时,当前轮次跳过。
默认留空,表示不跳过。
* 当前轮次因为 `跳过条件`被跳过时,是否直接结束审批链
* 启用
高优先级过滤条件(不启用肯定就没有作用)
* 描述
无明确用途
---
在设计器中设计审批节点时,由审批链控制的节点,不需要在去指定 `任务派遣`,可以完全在审批链中定义。即使指定了,也会被审批链中的值覆盖!
除了与审批人、岗位有关的属性以外,其他属性的含义、作用保持不变。
`名称`稍微有变化:会和审批链的名称拼接在一起
> 请注意:目前审批链还不支持多例(会签)
## 自定义任务超时时间和动态调整优先级
---
对于人工任务节点,在流程设计器中可以设置任务到期时间
![](/assets/wfl_user_task_approve.png)
支持ISO8601 标准的日期格式,也可以写流程变量。如PT8H(ISO8601标准支持),表明该节点的任务的限定时间是8小时。
HAP 实现了一个简单任务,每30分钟执行一次,会动态调整设置了到期日期的任务的优先级。
如何自定义超时时间的计算方式以及自定义优先级调整策略?
实现 `ICustomTaskProcessor` 即可:
```java
/**
* @param task 任务节点
* 动态设置task的优先级,调用getDueTime,获取任务剩余时间
* 建议不要改动其他属性,仅仅设置优先级
* @return 一般情况返回参数task
*/
Task processPriority(Task task);
/**
* @param startDate task的创建时间
* @param dueTime 当前task的任务的限定时间
*
* 根据task的创建时间和限定时间,返回任务的剩余时间,单位秒
*
* @return 返回经过计算后的任务剩余时间 ,负数表示超时时间
*/
Long getDueTime(Date startDate,Long dueTime);
/**
* 是否继续处理,如果返回false,不会再继续执行其他实现类
* */
boolean processorContinue();
int getOrder();
```
参考 HAP 提供的一个默认实现 `DefaultCustomTaskProcessor`
超时时间没做特殊处理,如果剩余时间不足三分之二将优先级上调一级,如果不足三分之一把优先级设置为高。超时则设置为最高(100)
1.首先实现 `getDueTime` 方法,该方法应该返回实际意义上,当前任务剩余的时间。
> 比如我们设置了PT8H,但是我们想让这个任务的时效是8个工时,则可以在这里写好处理逻辑
> 参数 `dueTime` 是一个 Long 类型的参数,它的值是设置的超时时间(比如8小时,任务的dueDate与startDate的时间差)
2.`processPriority` 方法则可以自定义优先级的调整规则,这里应该调用`getDueTime` 拿到任务的剩余时间或者超时时间,通过设置一定的规则,调整优先级(`task.setPriority(xx)`)
3.`getOrder` 方法用于实现类排序,数值越小,执行该实现类的优先级越高,框架的默认实现类order = 999,想只执行自己的实现类,设置一个较小的数值,重写 `processorContinue` 方法,并返回false 即可
工作流开发指南
---
## UserTask
---
### 指定审批人、组
在流程设计器中,选定`人工任务`节点,右边属性栏,点击`任务派遣` 弹出对话框
<img width='600' src='/assets/usertask-assignment.png'/>
其中:
* 指派对象
只能有一个人,可以点击`选择`按钮来从系统中选择员工
* 候选用户
可以添加多个,每个指定一个`员工工号`
* 候选组
可以添加多个,每个指定一个`岗位代码`
### 动态审批人、组
与 上面类似,不过动态的审批人和组不是选择的,而是通过表达式计算得来。
表达式有两种情况
* 引用变量
比如`${initiator}`, 其中`initiator` 就是一个变量
* 调用 service 方法
比如`${orgStructure.getDirector(initiator)}`,其中 `orgStructure` 是一个自定的用于工作流的 `bean`,参数则可以使用任意的变量、常量等
> `execution` 是一个固有的、特殊的变量,指代 `org.activiti.engine.delegate.DelegateExecution`,非常有用
关于自定义在工作流中用的 `bean`
HAP 提供一个 接口 `com.hand.hap.activiti.custom.IActivitiBean`
实现这个接口并被定义注册为 bean,其中的任何 `public` 方法都可以在工作流表达式中直接调用。
默认 bean 的 名字就是引用名,也可以覆盖接口的默认实现,指定名称。
### 审批动作
Hap 的工作流在审批的时候默认有两个标准的动作:
* 同意(APPROVED)
* 拒绝(REJECTED)
当审批者点击按钮以后,审批动作 id 会被保存到流程的共享变量区域。
key 为 `approveResult`,这个变量可以直接在表达式中使用。
```
${approveResult=='REJECTED'}
```
流程设计时,可以控制这两个按钮显示的文本;也可以控制只显示其中的一个。
允许自定义额外的审批动作,自动动作的 id 同样会保存在 `approveResult` 变量中,通常需要流程显示处理(比如选择网关)。
<img width='920' src='/assets/custom-approve-action.png'/>
### 自动结束流程(HAP 扩展特性)
当一个任务被拒绝时,绝大多数情况下,这个流程应该直接结束。
但在工作流中,`审批拒绝``审批同意` 仅仅是给变量赋的参数值不同而已,如果希望流程结束,应该加一个 `选择网关`,判断审批结果是否为 `拒绝` ,然后引导流程走向`结束事件`
显然,这很繁琐,尤其是当流程中`人工任务`节点比较多时。
HAP 做了一个优化:
> 如果一个`人工任务` 的下一个节点仍然是 `任务(Task 类型)`,那么 HAP 将会自动插入一个`选择网关`和`终止事件` 来自动做结束流程的操作
这个优化在流程的图上是看不出来的,用户完全无感知。
### 会签设置
自定义属性:`nrOfApproved``nrOfRejected`
集合
变量
任务派遣
完成条件
## 网关
---
选择网关
> 选择网关`必须` 指定一个默认的连线,否则会出现不固定的行为。
行网关
> 并行网关会在`所有连入`的连线都激活以后才会开始执行
## ServiceTask
---
## 待办通知
---
## 审批链
---
审批链功能不是 Activiti 的标准功能,属于 HAP 开发的外挂性质的扩展。
功能入口是在 `流程设计` 界面。
<img width='460' src='/assets/approve_chain_entry.png'/>
点击 编辑图标 进入该流程的审批链配置界面
<img width='900' src='/assets/approve_chain@2x.png'/>
在这个编辑页面中,所有的 `UserTask` 节点会以 标签页的形式自动列出来。
切换标签页,下方表格中的数据会自动刷新为对应节点的数据。
上方的 操作按钮 是针对每个 标签页 操作的,并非针对整个页面。
主要属性说明:
* 名称
自定义,任意。`不允许重复`
节点原始名称 和 审批链的名称 拼接起来 作为运行时的名称。
* 审批人
内置 3 种
* 申请人(自己)
* 上级(申请人直接领导)
* 申请人部门领导
其他情况统统归为 `自定义表达式`
> 注意,这个功能要求流程的初始化器(Initiator)必须指定为 `initiator`
* 审批岗位
支持选择系统中的`岗位`,也支持自定义的`表达式`
> 目前在指定了审批人的情况下,再指定审批岗位是无效果的
* 表单
允许该轮次的审批显示指定的单据明细页面。
如果没有指定,则显示该节点原始设置的值。
* 顺序号
用来控制审批的先后 (目前尚不支持多人同时在同一轮次审批)
* 跳过条件
表达式,有值,且值为 true 时,当前轮次跳过。
默认留空,表示不跳过。
* 当前轮次因为 `跳过条件`被跳过时,是否直接结束审批链
* 启用
高优先级过滤条件(不启用肯定就没有作用)
* 描述
无明确用途
---
在设计器中设计审批节点时,由审批链控制的节点,不需要在去指定 `任务派遣`,可以完全在审批链中定义。即使指定了,也会被审批链中的值覆盖!
除了与审批人、岗位有关的属性以外,其他属性的含义、作用保持不变。
`名称`稍微有变化:会和审批链的名称拼接在一起
> 请注意:目前审批链还不支持多例(会签)
流程设计器教程
---
# 1.开始事件和结束事件
---
对应着流程的开始和结束。
> 应该保证每个分支都可以从开始走到结束
## 开始事件
开始事件用来指明流程在哪里开始。开始事件的类型(流程在接收事件时启动, 还是在指定时间启动,等等),定义了流程如何启动。
> 一般使用第一个空的开始事件就可以了,需要手动启动流程
*属性*
![](/assets/act_vacationReq_bg_v.png)
* 初始化器
当流程启动时,把当前登录的用户保存到哪个变量名中,可以在表达式里直接引用该变量
* 表单属性
当执行到开始事件时,所有的流程变量都是可用的,但是可能需要一些用于表单展示的自定义变量,此时可以在表单属性中定义,将会保存到流程的`共享变量`区域
![](/assets/act_vacationReq_form.png)
如图是`请假流程`的开始事件的表单属性,在这里定义的变量,在`工作流测试页面`会自动渲染成表单
支持以下的几种表单属性类型:
* string (org.activiti.engine.impl.form.StringFormType)
* long (org.activiti.engine.impl.form.LongFormType)
* enum (org.activiti.engine.impl.form.EnumFormType)
* date (org.activiti.engine.impl.form.DateFormType)
* boolean (org.activiti.engine.impl.form.BooleanFormType)
> 括号里是作为流程变量存储的对应JAVA类
表达式和变量
如果设置了`变量`,需要通过变量名来引用变量,表达式同理
> 默认则是把id作为变量名使用
* 必须 如果勾选了,提交表单时没有提供该属性则抛出异常
* 可读 不勾选则不会进行自动渲染显示,但是还是可以提交
* 可写 不够勾选,还提交该属性,也会抛出异常
## 结束事件
结束事件表示(子)流程(分支)的结束。 结束事件都是触发事件。 这是说当流程达到结束事件,会触发一个结果。 结果的类型是通过事件的内部黑色图标表示的。
> 一般使用一个空的结束事件就行了,意味着到达事件时不会指定抛出的结果。 这样,引擎会直接结束当前执行的分支,不会做其他事情。
### 自动结束流程(HAP 扩展特性)
当一个任务被拒绝时,绝大多数情况下,这个流程应该直接结束。
但在工作流中,`审批拒绝``审批同意` 仅仅是给变量赋的参数值不同而已,如果希望流程结束,应该加一个 `选择网关`,判断审批结果是否为 `拒绝` ,然后引导流程走向`结束事件`
显然,这很繁琐,尤其是当流程中`人工任务`节点比较多时。
HAP 做了一个优化:
> 如果一个`人工任务` 的下一个节点仍然是 `任务(Task 类型)`,那么 HAP 将会自动插入一个`选择网关`和`终止事件` 来自动做结束流程的操作
这个优化在流程的图上是看不出来的,用户完全无感知。
# 2.任务
---
常用的是人工任务,和服务任务
## 人工任务(UserTask)
![](/assets/act_vacationReq_userTask.png)
### 任务派遣
**指定审批人、组**
点击`任务派遣` 弹出对话框
<img width='600' src='/assets/usertask-assignment.png'/>
其中:
* 指派对象
只能有一个人,可以点击`选择`按钮来从系统中选择员工
* 候选用户
可以添加多个,每个指定一个`员工工号`
* 候选组
可以添加多个,每个指定一个`岗位代码`
**动态审批人、组**
与 上面类似,不过动态的审批人和组不是选择的,而是通过表达式计算得来。
`表达式`有两种情况
* 引用变量
比如`${initiator}`, 其中`initiator` 就是一个变量
* 调用 service 方法
比如`${orgStructure.getDirector(initiator)}`,其中 `orgStructure` 是一个自定的用于工作流的 `bean`,参数则可以使用任意的变量、常量等
> `execution` 是一个固有的、特殊的变量,指代 `org.activiti.engine.delegate.DelegateExecution`,非常有用
关于自定义在工作流中用的 `bean`
HAP 提供一个 接口 `com.hand.hap.activiti.custom.IActivitiBean`
实现这个接口并被定义注册为 bean,其中的任何 `public` 方法都可以在工作流表达式中直接调用。
默认 bean 的 名字就是引用名,也可以覆盖接口的默认实现,指定名称。
### 表单的标识Key
用于在待办明细页面中,动态渲染页面,设置为表单html页面的路径
### 表单属性
跟开始事件的表单属性一样
**审批动作**
Hap 的工作流在审批的时候默认有两个标准的动作:
* 同意(APPROVED)
* 拒绝(REJECTED)
当审批者点击按钮以后,审批动作 id 会被保存到流程的`共享变量`区域。
key 为 `approveResult`,这个变量可以直接在表达式中使用。
```
${approveResult=='REJECTED'}
```
流程设计时,可以控制这两个按钮显示的文本;也可以控制只显示其中的一个。
允许自定义额外的审批动作,自动动作的 id 同样会保存在 `approveResult` 变量中,通常需要流程显示处理(比如选择网关)。
<img width='920' src='/assets/custom-approve-action.png'/>
### 会签设置
会签通过设置`多实例`属性来实现,有串行和并行两种模式。
> 三条竖线表示实例会并行执行。 三条横线表示顺序执行。
<img width='920' src='/assets/activiti_parallel.png'/>
`集合` 应该返回一个字符串数组,表示用户集合
> 并行执行 会立刻为所有集合成员创建任务实例
> 串行执行 会依次创建任务实例,完成一个才会创建下一个
`元素变量` 遍历用户集合的单个对象变量名称
> 任务派遣 设置${元素变量}即可
`完成条件`
> activiti 标准会签,默认有 3 个参数, 可以作为结束条件考量依据.
分别是
* nrOfInstances(实例个数,根据集集合表达式中获取的对象个数确定)
* nrOfCompletedInstances(已经完成的实例个数,比如已经同意或者拒绝的)
* nrOfActiveInstances(还未完成的实例个数)
>
hap 自定义了两个:
* nrOfApproved(同意的实例个数)
* nrOfRejected(拒绝的实例个数)
## 服务任务(ServiceTask)
用来调用外部java类
有三种方式
### 类名
`类名`属性设置类的完整限定名
比如`com.hand.hap.activiti.demo.DemoServiceTask`
> 需要实现JavaDelegate接口
类只会初始化一次, 类似 servlet 的模式。
### 代理表达式
执行解析代理对象的表达式,直接通过表达式确定代理对象
比如`$(demoServiceTaskDelegate)`
> 参考com.hand.hap.activiti.demo.components.DemoServiceTaskDelegate 实现JavaDelegate接口和IActivitiBean
注意是用$符号,这是delegateExpression,与普通的表达式有区别
### 表达式
可以调用指定方法
`#{demoServiceTaskDelegate.method1(execution,task2Output)}`
# 3.网关
网关用来控制流程的流向
网关显示成菱形图形,内部有有一个小图标。 图标表示网关的类型
### 单一网关
内部图标是一个“X”
当流程执行到这个网关,所有外出顺序流都会被处理一遍。 通过设置`跳转条件`控制流程走向。
> 比如 ${approveResult == 'REJECTED'},表示拒绝后的流程走向。
可以设置`默认跳转`,当其他所以顺序流的跳转条件都返回false时触发。
> 注意如果多个顺序流的条件结果为true,单一网关只会选择一个执行。
### 并行网关
内部是一个“+”图标
并行网关的功能是基于进入和外出的顺序流的:
* 分支: 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
* 汇聚: 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。
注意,如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
与其他网关的主要区别是,并行网关*不会解析条件*。 即使顺序流中定义了条件,也会被忽略。
>参考[Activiti5.16中文手册](http://www.mossle.com/docs/activiti/index.html)
\ No newline at end of file
# 消息机制 # 消息机制
## 1.简介 ## 1.简介
融租易 的消息系统提供`唯一``广播`以及`主题`三种模式,实现方式为 RabbitMQ。 融租易 的消息系统提供`唯一``广播`以及`主题`三种模式,实现方式为 RabbitMQ。
### 1.1 RabbitMQ介绍 ### 1.1 RabbitMQ介绍
RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦。rabbitmq多应用于批量数据异步处理、并行任务串行化,高负载任务的负载均衡等 重量级,高并发,异步高可靠性场景。 RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦。rabbitmq多应用于批量数据异步处理、并行任务串行化,高负载任务的负载均衡等 重量级,高并发,异步高可靠性场景。
### 1.2 配置rabbit ### 1.2 配置rabbit
(1)用户要先在 `applicationContext-rabbitmq.xml` 中 添加`<beans:import resource="rabbitmq.xml"/>` (1)用户要先在 `applicationContext-rabbitmq.xml` 中 添加`<beans:import resource="rabbitmq.xml"/>`
(2)然后在`config.properties`中自行添加mq相关的配置如图: (2)然后在`config.properties`中自行添加mq相关的配置如图:
![](/assets/config.png) ![](/assets/config.png)
## 2 自定义消息 ## 2 自定义消息
在融租易的接口管理的消息队列模块定义功中,提供了自定义队列和交换机的功能,可以根据配置实现自定义的队列和交换机的匹配,避免了在xml中的繁琐配置。 在融租易的接口管理的消息队列模块定义功中,提供了自定义队列和交换机的功能,可以根据配置实现自定义的队列和交换机的匹配,避免了在xml中的繁琐配置。
### 2.1 定义交换机 ### 2.1 定义交换机
在接口管理的消息队列定义模块中,首先进行交换机的定义,界面如图:![](/assets/exchange.png)注意: 在接口管理的消息队列定义模块中,首先进行交换机的定义,界面如图:![](/assets/exchange.png)注意:
交换机名称不可以重复定义,一个交换机可以对应多个队列。 交换机名称不可以重复定义,一个交换机可以对应多个队列。
交换机类型可以分为**direct\(唯一模式\),topic\(主题模式\),fanout\(广播模式\),**rabbitmq会根据你的交换机类型和定义的路由键,完成消息的转发**。** 交换机类型可以分为**direct\(唯一模式\),topic\(主题模式\),fanout\(广播模式\),**rabbitmq会根据你的交换机类型和定义的路由键,完成消息的转发**。**
持久化(durable):交换机在服务关闭后,清除与否。 持久化(durable):交换机在服务关闭后,清除与否。
自动删除(auto-delete):当交换机没有队列绑定时,删除与否。 自动删除(auto-delete):当交换机没有队列绑定时,删除与否。
### 2.2 定义队列和路由键 ### 2.2 定义队列和路由键
定义完交换机后,你还需要定义你的队列和相应的匹配模式(既路由键)界面如图:![](/assets/queue.png)注意: 定义完交换机后,你还需要定义你的队列和相应的匹配模式(既路由键)界面如图:![](/assets/queue.png)注意:
队列名称不可以重复,但是一个队列可以对应多个交换机。 队列名称不可以重复,但是一个队列可以对应多个交换机。
匹配模式(routing-key):此处的匹配模式即为路由键 匹配模式(routing-key):此处的匹配模式即为路由键
持久化(durable):队列在服务关闭后,清除与否。 持久化(durable):队列在服务关闭后,清除与否。
自动删除(auto-delete):当队列没有绑定交换机时,删除与否。 自动删除(auto-delete):当队列没有绑定交换机时,删除与否。
私有队列(exclusive): 仅创建者可以使用的私有队列,断开后自动删除. 私有队列(exclusive): 仅创建者可以使用的私有队列,断开后自动删除.
## 3 发送消息/接收消息 ## 3 发送消息/接收消息
在融租易中,消息的发送和接收都提供了可以直接调用的接口 在融租易中,消息的发送和接收都提供了可以直接调用的接口
### 3.1 消息的匹配规则 ### 3.1 消息的匹配规则
1.唯一模式\(**Direct Exchange**\): 1.唯一模式\(**Direct Exchange**\):
处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “hls”,则只有被标记为“hls”的消息才被转发,不会转发hls.sys,也不会转发hls.fnd,只会转发hls。 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “hls”,则只有被标记为“hls”的消息才被转发,不会转发hls.sys,也不会转发hls.fnd,只会转发hls。
2.广播模式\(**Fanout Exchange**\): 2.广播模式\(**Fanout Exchange**\):
不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。 不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
3.主题模式\(**Topic Exchange**\): 3.主题模式\(**Topic Exchange**\):
将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“\#”匹配一个或多个词,符号“\*”匹配不多不少一个词。因此“hls.\#”能够匹配到“hls.sys.adaptor”,但是“hls.\*” 只会匹配到“hls.sys”。 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“\#”匹配一个或多个词,符号“\*”匹配不多不少一个词。因此“hls.\#”能够匹配到“hls.sys.adaptor”,但是“hls.\*” 只会匹配到“hls.sys”。
### 3.2 发送消息 ### 3.2 发送消息
融租易中,通过调用`IRabbitProducerService`接口中的`sendMessage(JSONObject json)`方法,来实现消息的发送 融租易中,通过调用`IRabbitProducerService`接口中的`sendMessage(JSONObject json)`方法,来实现消息的发送
注意: 注意:
接口调用时必须使用spring中的注入方式。 接口调用时必须使用spring中的注入方式。
json必须按照格式如: json必须按照格式如:
```json ```json
{ {
...@@ -96,20 +96,20 @@ json ...@@ -96,20 +96,20 @@ json
} }
``` ```
### 3.3 接收消息 ### 3.3 接收消息
融租易中对消息的接收进行了统一处理,只需要单独编写业务的实现类即可(此处必须实现IRabbitMessageConsumerService接口),消息会先被内部的消息监听接口统一处理,然后再根据消息中的apiName找到对应的接口实现类,调用其中的process方法。 融租易中对消息的接收进行了统一处理,只需要单独编写业务的实现类即可(此处必须实现IRabbitMessageConsumerService接口),消息会先被内部的消息监听接口统一处理,然后再根据消息中的apiName找到对应的接口实现类,调用其中的process方法。
示例代码: 示例代码:
```java ```java
@Service @Service
public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService { public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService {
@Autowired(required = false) @Autowired(required = false)
private IRabbitProducerService iRabbitProducerService;//消息发送类 private IRabbitProducerService iRabbitProducerService;//消息发送类
@Autowired @Autowired
private IXXXService service;//业务类 private IXXXService service;//业务类
@Override @Override
public String getApiName() { public String getApiName() {
...@@ -118,9 +118,9 @@ public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService { ...@@ -118,9 +118,9 @@ public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService {
@Override @Override
public void process(JSONObject json) { public void process(JSONObject json) {
//业务处理 //业务处理
service.doSomething(json) service.doSomething(json)
//返回消息 //返回消息
ResponseInfo responseInfo = null; ResponseInfo responseInfo = null;
try { try {
responseInfo = RabbitMQUtils.getResposeInfo(json); responseInfo = RabbitMQUtils.getResposeInfo(json);
...@@ -137,6 +137,3 @@ public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService { ...@@ -137,6 +137,3 @@ public class ConsumerDemoServiceImpl implements IRabbitMessageConsumerService {
``` ```
### ###
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment