目录接口篇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
gds-parent  根目录
gds-wms-parent 仓库运营系统服务
gds-wms 仓库运营系统服务
src
common 公共类
utils 工具类 命名以Util结尾的类
domain 业务对象
enums 枚举类
exception 放自定义异常类
mapper 如果用JPA操作数据库用repository 放命名以Repository结尾的类,
用mybaits操作数据库用mapper 放命名以Mapper结尾的类
remote 远程调用,放fegin调用接口
consumer 存放[调用]外部Feign服务的类 命名以Client结尾
fallback 存放consumer调用降级处理类 命名以FallbackFactory结尾
provider 存放对外提供的HTTP(Feign)类 命名以Remote结尾
service 放业务逻辑处理接口 命名以Service结尾的类
impl 放业务处理实现`类 命名以对应接口名+Impl结尾的类(后面同理)
web 放controller 命名以Controller结尾的类
...
resources
mapper 存放sql的xml文件
static 存放静态资源(js/css/img....)
templates 存放页面模板
error 存放错误相关的页面
wms 存放业务相关的页面
gds-wms-api 仓库运营系统服务Api
gds-wos-parent 仓库作业系统服务
gds-wos 仓库作业系统服务
gds-wos-api 仓库作业系统服务Api

接口篇

以下为以前开发自己设定的一些规范,供以后参考

1. 返回类型

  1. 所有接口返回类型都为ResponseMsg
  2. 除了与外界交互的接口,不允许其它返回类型为ResponseMsg的方法

2. 对外接口请求路径规则

  1. 提供给app用的接口统一以[/app]开头
  2. 提供给外部系统调用的接口统一以[/api]开头
  3. 提供给页面的接口统一以[/page]开头
阅读更多

异常处理与日志篇

异常处理

  1. 异常处理不需要手动输出日志
      - 全局异常处理会帮你做这件事
  2. 遇到的所有异常都包装成[业务异常]or[系统异常]后往上抛
  3. 业务异常(校验异常等) 对应类:BusinessRuntimeException
      常用方法:
      1. throw BusinessRuntimeException.buildBusyException(EnumCommomSysErrorCode.MQ_ERROR, “消费异常”, parm);
      2. throw BusinessRuntimeException.buildBusyException(parm,EnumCommomSysErrorCode.MQ_ERROR,);
  4. 系统异常(404,MQ联不通等) 对应类:SystemRuntimeException
      常用方法:
      1. throw SystemRuntimeException.buildSysException(EnumCommomSysErrorCode.FILE_TYPE_NOT_SUPPORT, e, parm);
      2. throw SystemRuntimeException.buildSysException(EnumCommomSysErrorCode.FILE_TYPE_NOT_SUPPORT, “文件类型不支持”,e, parm);

业务日志打印

  1. 对HTTP请求(Controller)进来参数,不需要打印(对于Dubbo/MQ等入参还是需要打印的)
      - 已经做了拦截器全局进行打印

数据库篇

脚本提交

统一使用Flyway进行统一的管理
svn://172.16.30.16:20044/G2G_DS/trunk/WMS/wms_db_script

Dao操作相关

  1. 对数据库表更新/删除操作不能使用ID作为’第一’条件, 如

    错误用法

    1
    update parcel set a="value" where id=123

    正确用法 应用业务主键作为条件

    1
    update parcel set a="value" where fpxTrackingNo="fpx20190402"
  2. 数据库查询不允许使用select *, 应使用select a,b,c

MQ篇

MQ队列命名规范

  1. 业务线_队列的生产者项目名_消费的项目名称_[Q/R/X]_自定义标识
    如 : GDS_WMS_WOS_Q_FORECAST
      对应的Exchange名为:GDS_WMS_WOS_X_FORECAST
      对应的Routing key名为:GDS_WMS_WOS_R_FORECAST
    ;
      对应的死信队列名为:GDS_WMS_WOS_Q_FORECAST_DEAD
      对应的死信Exchange名为:GDS_WMS_WOS_X_FORECAST_DEAD
      对应的死信Routing key名为:GDS_WMS_WOS_R_FORECAST_DEAD
  2. 生产者队列的消息统一通过 [MQ的shovels插件] 转发到消费者队列
  3. 生产者不需要创建死信队列
  4. 消费者队列必须测试一下消息失败是否会进入对应的死信 这,很重要

MQ队列/Exchange 定义规范

  1. [生产者端]需要定义队列+Exchange 并且建立队列和Exchange的绑定关系
    • 队列需要定义:

      durable=true
      exclusive=false, autoDelete=false
      队列创建使用rabbitAdmin.declareQueue(queue); 防止队列窜到别的VH中

    • Exchange 需要定义

      durable=true
      autoDelete=false
      Exchange创建使用rabbitAdmin.declareExchange(exchange);防止队列窜到别的VH中

    • 建立绑定关系

      rabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(exchange).with(“GDS_WMS_WMS_R_TASK_ASYNC_CONSUME”));

例子

阅读更多

待办篇

待办目录

  • [X] 基于Junit5的新测试用例规范
  • [ ] 基于新测试用例的demo
  • [ ] MQ重复消费问题解决
  • [X] 根据请求ID追踪调用链所有日志

系统改造

  • [ ] 新建GDS公用工程,存放Wms与Wos公用代码(暂定)

Redis篇

redis缓存Key规范

  1. Key前缀统一使用常量:
    ConstantsString.RedisConstant.REDIS_CACHE_PREFIX

单元测试篇

关于测试类的规范 (暂定)

  1. 单元测试应该是不依赖于别的单元测试的
  2. 所有单元测试应该都得回滚,如果存在异步处理的情况,应尽可能把主线程与fork线程拆成2个测试类方法进行测试
  3. 每个测试类/测试方法应写上对应的名称@DisplayName
  4. 每个接口,都必须写一个正向测试方法
  5. 关于测试类的类名:测试类与被测试的类的路径需要一致,名字也需要对应,如:
1
2
3
com.fpx.wms.service.impl.InstockServiceImpl
↓对应↓
com.fpx.wms.service.impl.InstockServiceImplTest
  1. 关于测试类的方法名: 方法名尽可能为成功的条件如shouldSuccessAfterPay(),而方法具体用来测试哪个场景的,我们已经使用了@ DisplayName来描述,无须担心
  2. 对于结果,需要适应assert断言输出与结果是否一致(这才能算是一个单元测试)
  3. 断言统一使用AssertJ框架,使用Assertions.assertThat()进行处理

可以参考\gds-parent\gds-wms-parent\gds-wms\src\test\java\com\fpx\gds\wms\service\exceptionhandle\impl在SVN版本为2962时提交的代码为参考

阅读更多