SPI包结构

SPI由model、业务码、枚举以及接口组成,但我们必须考虑如何对接口功能进行版本控制

如果我们公开一个方法,那么客户端很可能基于此方法进行业务设计,这就意味着客户端隐式地和我们耦合在了一起。

另外,不同的业务线依赖的SPI的jar版本可能不同,我们将面临多版本SPI并存的情况。你无法强制客户端升级,因为新的SPI的model可能有调整,升级之后,客户端原有的逻辑也必须重构一遍。

所以我们必须对接口方法进行版本控制,而且要做好向后兼容。

考虑到以上情况,我们SPI包结构如下:

com.lianjia.sh.loupan.spi
     source //业务枚举包
         ImageType.class //业务枚举
     model  //model包
           City.class
           Company.class

     LoupanBizCode.class  //SPI的业务码
     CitySpi.class      //SPI接口 
     CompanySpi.class  //SPI接口

包前缀规范

首先,package前缀的规范: com.lianjia.sh.项目名.功能模块名.spi。也可以说,包前缀为SPI模块名。如果功能简单,则可以忽略功能模块。下面,我列举几个正确的包前缀:

  • com.lianjia.sh.loupan.search.spi
  • com.lianjia.sh.loupan.core.spi
  • com.lianjia.sh.loupan.statistics.spi

子包目录

子包目录有model、枚举包、其他等。

所有的SPI接口和业务码属于com.lianjia.sh.项目名.功能模块名.spi包,和model等子包层级并列。

包结构示例

下面示例为loupan-search-spi 模块的包结构:

com.lianjia.sh.loupan.search.spi
    source
           ImageSource.class     —- 图片类型
           OtherEnumSource.class —- 其他业务枚举
    model
           City.class           —- 业务实体
           Resblock.class       —- 业务实体
           OtherEntity.class    —- 业务实体 

    LoupanBizCode.class    -- 楼盘字典业务码
    ResblockSpi.class      —- 公开出去的SPI
    CitySpi.class             —- 公开出去的SPI
    OtherSpi.class         —- 其他SPI接口

接口方法

为了对SPI接口的方法进行版本控制,我们约定:所有接口的方法都要添加版本号后缀,比如 findCitysV1、findCitysV2、autoSearchV2。

业务码

一般REST接口都会声明一系列业务错误码,这便于客户端定位问题。

lorik-spi-view提供了标准业务码:com.dooioo.se.lorik.spi.view.support.BizCode,推荐集中声明在接口中(如果业务码字段不是public&& static ,自动生成文档时将忽略)。

注意:code值在900000-1000000之间的业务码是API网关及通用框架抛出的错误。

BizCode有个静态方法: BizCode.toCodes(BizCode...codes)将多个业务码合并成以逗号隔开的字符串,可复制到LorikRest(codes={code1,code2,…})里,以声明此方法可能抛出的业务码值,此处的codes为int型数组,是BizCode的code值,也可以声明为int型静态常量,示例如下:

 //code常量
 public interface Codes{
        int CITY_NOT_EXISTS=210000;
         …..
 }

//业务码集中声明
public interface XXXBizCode{
    BizCode CITY_NOT_EXISTS=new BizCode(Codes.CITY_NOT_EXISTS, "城市不存在");
        …
}

//SPI的方法,一个微服务可能有很多业务码,但我们可声明当前方法抛出的业务码
@LorikRest(value={Feature.NullTo404},
    codes={Codes.CITY_NOT_EXISTS})
    @RequestMapping(value=“/v1/citys/{gbCode}”,method=RequstMethod.GET)
    public City findByIdV1(@PathVariable(value=“gbCode”)int gbCode);

SPI业务码类的命名,推荐为:XXXBizCode,前缀一般为SPI模块名。

下面示例为mini楼盘的业务码:


package com.lianjia.sh.samples.loupan.spi;

import com.dooioo.se.lorik.spi.view.support.BizCode;

/**
  * 楼盘标准业务码
  * @author huisman 
  * @Copyright (c) 2016, Lianjia Group All Rights Reserved.
*/
public interface LoupanBizCode {

    /**
     *  城市不存在。
     */
    BizCode CITY_NOT_EXISTS=new BizCode(21000, "城市不存在");

    /**
     * 商圈不存在
     */
    BizCode BIZCIRCLE_NOT_EXISTS=new BizCode(22000, "商圈不存在");

    /**
     *  楼盘不存在
     */
   BizCode REBLOCK_NOT_EXISTS=new BizCode(23000, "楼盘不存在");


    /**
     *  行政区域不存在
     */
   BizCode DISTRICT_NOT_EXISTS=new BizCode(24000, "区域不存在");

}

业务码可在服务实现时配合com.dooioo.se.lorik.core.web.result.Assert抛出:


  @Service
  public class CityService{

      public void updateInvalid(int id){
          City city=cityDao.findById(id);
          Assert.found(city !=null,LoupanBizCode.CITY_NOT_EXISTS);
          //other logic
      }
  }

业务枚举

业务实现所涉及的业务枚举,推荐声明在SPI包里。

© RD@上海链家 all right reserved,powered by Gitbook文件修订时间: 2016-11-01 01:48

results matching ""

    No results matching ""