Commit 7baade93 authored by custom's avatar custom

Merge origin/master into master

parents 67554f10 5c79434d
...@@ -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**
......
# 消息机制 # 消息机制
## 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