巨商会项目规范&约定

通用约定

  • 项目名称
    web项目以jsh-web开头,dubbo项目以jsh-service开头,其他项目视具体情况取与项目相对应的名字。

  • 包名规则
    groupId + artifactId + 代码分类 + [业务分类] 然后去除重复单词得到实际的包名,其中业务分类可选,可直接体现在类名上。

  • 数据库相关的Java Bean(Entity)命名规则
    数据库对应的Entity类,其类名和属性名应该与数据库字段对应起来。Java中使用驼峰格式命名,数据库中采用下划线连接小写单词的命名方法。

  • 基础框架
    以spring-boot为入口的spring框架

  • Spring Bean声明方式
    需要对外提供服务的Bean(dubbo接口)和内部需要使用的第三方bean以xml的形式声明;
    项目内部使用的bean以注解形式声明。

  • 日志约定
    使用slf4j的方式打印日志。生产环境使用info级别的日志,debug日志仅供内部调试使用。
    对外提供服务的方法(web controller和dubbo service)每次收到请求后,对应的AOP切面都会打印对应的access log(包括出参,入参等),
    因此开发人员只需要按照实际需要打印中间过程的日志即可。

  • 异常处理
    采用AOP的方式为对外提供服务的方法进行了异常的处理及封装,因此如不需要针对不同的异常进行不同的处理,则不需要捕获异常,直接抛出即可。
    对于内部校验失败等原因需要终端处理流程的情况,直接抛出JshServerException即可。

  • Groovy使用
    工程内基本都集成了groovy插件,可以直接使用groovy编写代码。对单元测试中使用的groovy代码不做要求,能达到目的即可;
    对于正式代码中的groovy,必须添加CompileStatic注解,以保证其性能。对于IDE,14.0之后的IDEA本身集成了对groovy的支持

  • IDE相关
    建议使用14.0.6版本之后的IDEA,其本身集成了对groovy的支持;
    或者使用4.5版本之后的Eclipse并安装groovy插件(推荐spring封装的eclipse版本STS)

  • 本地临时配置
    项目中不同环境对应的配置参数定义在pom.xml中的profile,需要针对不同的环境选择不同的profile。
    对于需要本地临时改变的配置参数,可以在src同级下的config/application.properties中更改。
    此文件被git忽略,需要手工添加,里面的参数值的优先级高于src/main/resource/application.properties里定义的参数值

  • 常量定义
    常量需要以枚举的方式定义,其中枚举类中至少需要包含常量值和常量描述两个属性,其余属性可视情况添加。

  • mybatis分页查询
    mybatis的分页查询代码在jsh-service-common里实现,原理为使用mybatis的拦截器机制,
    在sql生效执行前分别生产对应的总数查询和分页查询sql并分别执行,其中
    1. 将查询到的总数放到ThreadLocal里,需要调用PaginationInterceptor的静态方法getPaginationTotal单独拿取
    2. 将分页查询sql得到的结果返回给调用者,最后在调用处(一般为service层)将总数和结果列表拼装成一个Page对象返回

    分页查询的触发条件为:
    1. 查询方法名以get,find,load等单词开头(定义在mybatis-config.xml中)
    2. 查询方法参数中包含mybatis提供的RowBounds类

web项目约定

  • 启动方式
    web项目默认采用自启动的方式运行,即运行其中的 xxApplication类即可将项目启动起来;
    如果要将其部署在tomcat或者其他容器下运行,则编译的时候需要显式的禁用名为standalone的profile

  • Controller定义规则
    返回页面的Controller,需要继承BaseController,类名以Controller结尾,其url前缀定义需包含和类名具有相同含义的单词。
    Rest风格的Controller,需要继承BaseRestController,类名以RestController结尾,其url前缀需要在页面url前缀基础上添加/rest
    页面Controller的接口方法返回值必须为String,方法的第一个参数必须为Map<String, Object> model。 Rest风格Controller的接口方法的返回值必须为Object。 url采用小写单词结合中划线的方式书写,不要采用驼峰写法。

  • 前后台消息传递
    如果后台有info或者warning级别的消息需要传递到页面,调用MsgHandler的具体方法添加即可,可以传递多个info或者warning消息到前台,可以在流程的任何地方调用。
    如果处理过程中有Exception抛出,则AOP切面会将Exception中的信息作为error信息传递到前台。

  • 静态资源路径
    图片,css,js等静态资源,全部存放在webapp/static下;
    其中第三方的放在third下,保持第三方资源发布时的目录结构不变;
    项目本身的资源放在对应的css, js, img等文件夹下。

dubbo项目约定

  • 项目划分
    每个dubbo工程分为api和provider两个工程,
    api工程定义接口及相关参数,供其他项目依赖使用,
    provider工程运行在服务器端,提供相关接口的实现。

  • 接口的出参入参
    接口的返回值必须继承BaseResult。
    接口的参数中至少需要有一个参数是BaseParam或者其子类。

  • 接口返回值的简易写法
    接口的返回值如果为null,在在返回给客户端之前,AOP切面会构造一个对应的success为true示例,并返回给客户端。 如果返回值不为null,但是success为null,则AOP切面会将返回值的success字段赋值为true。

  • dubbo接口返回值校验
    如果服务端返回结果的success为false时客户端需要直接终端当前流程,则客户端可以在拿到返回结果后直接调用DubboUtil的checkServiceResult进行校验。

  • 本地开发调试
    本地开发dubbo服务时,将dubbo直接作为jar依赖来调用的方式会引起事务,spring多context,自动配置等问题,因此要求本地开发测试dubbo服务时采用正常的dubbo调用方式。
    为了避免本地dubbo和集成测试环境的互相干扰,约定集成测试环境使用10.168.3.19的zookeeper作为注册中心,本地环境使用10.168.3.18的zookeeper作为注册中心。 本地调试时,使用dubbo提供的直连提供者的方式进行调试。
    具体方式为:

    1. 在开发provider接口时,将该provider下对应的接口和本地测试地址列表放到src/test/resources/dubbo-resolve.properties里
    2. 客户端调试接口时,将对应provider的dubbo-resolve.properties的内容合并到${user.home}/dubbo-resolve.properties(或者-Ddubbo.resolve.file指定的文件)里
    3. 使用10.168.3.18的zookeeper作为注册中心启动provider
    4. 启动客户端连接本地provider进行调试。如果需要在IDE里执行断点跟进的操作,需要在config/application.properties里将dubbo.consumer.default.timeout设置为一个较大的值,防止调试时dubbo因超时中断调用。