1.2 SpringBoot开发规范
1.2.1 开发规范的作用
开发规范是基于某种特定的开发语言和架构,进行开发的基本原则和推荐方式,在开发过程中有迷惑时进行参照的指南。 开发规范不同于编码规则,但一定要包含编码规则。
编码规范有以下几点意义:
- (1) 编码规范可以最大限度的提高团队开发的合作效率。
- (2) 编码规范可以尽可能的减少一个软件的维护成本,并且几乎没有任何一个软件,在其整个生命周期中,均由最初的开发人员来维护 。
- (3) 编码规范可以改善软件的可读性,可以让开发人员尽快而彻底地理解新的代码
- (4) 规范性编码还可以让开发人员养成好的编码习惯,甚至锻炼出更加严谨的思维
本节关于开发规范的内容摘录自互联网上搜索到的经验,同时结合实际工作中的理解所整理,由于各个团队的开发制度或公司要求有所不同,开发规范不一定适用于所有团队,以下内容仅仅只是作为学习使用SpringBoot框架进行项目开发的参考。
1.2.2 代码仓库规范
1.2.2.1 公共组件
公共组件通常指Java库,提供特定问题的处理程序包。公共组件的命名规范为:
- (1) 分组编号:com.companyname.library 固定取值
- (2) 组件名称:name name根据组件名称定义
- (3) 组件版本:x.y.z x.y.z根据组件实际版本情况定义
1.2.2.2 服务组件
服务组件通常指可以独立部署,运行,维护的服务程序包,应用组件的命名规范为:
- (1) 分组编号:com.companyname.server固定取值
- (2) 组件名称:name name根据组件名称定义
- (3) 组件版本:x.y.z x.y.z根据组件实际版本情况定义
1.2.2.3 开发环境
- (1) 开发环境:JDK1.8+
- (2) 开发工具:IntelliJ IDEA 2017(安装Lombok Plugin)
- (3) 构建工具:Maven3.x
- (4) 代码管理工具:Git /TortoiseGit,根据公司或者组织统一配置管理(有得公司使用SVN)。
本文所介绍的SpringBoot示例都是基于以下环境制作:
-
开发工具:IDEA
可从官网下载https://www.jetbrains.com/idea/download/
-
Java
JDK版本号:1.8 -
Maven
Maven版本号:3.5.2
1.2.3 工程结构规范
一个工程对应代码仓库中的一个仓库,项目结构是指一个基于Maven创建的项目目录结构。公共组件项目,通常会创建一个Maven普通项目。服务组件项目,通常会创建一个Maven聚合项目,并在聚合项目目录下创建多个继承Maven聚合项目的Maven模块,它们一起作为服务组件项目的组成部分。
- (1) 工程名称
使用英文作为仓库、项目、项目根目录、包结构、配置文件、代码文件、组件(公共组件,服务组件)的名称。使用中文作为用于代码仓库描述、模块功能描述、类描述、方法描述等。
Maven工程的命名、版本以及描述信息如:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LMUnaBhD-1582182974029)(https://zone-7.github.io/img/springboot/1.2.3.png)]
-
(2) 模块命名
模块名称:{项目名称}-{模块名称} 模块名称简洁体现职责 ,使用模块名字作为模块组件的名称。例如:系统管理模块名称:sys -
(3) 项目目录
项目目录遵循Maven约定目录格式 -
(1) 源码目录指:{项目目录}/src/main/
-
(2) 打包定义目录:src/main/assembly
-
(3) 代码目录:src/main/java
-
(4) 资源目录:src/main/resources
-
(5) 数据库脚本归档:/db
-
(6) 内部依赖数据归档:/data
-
(7) 文档目录:src/main/docs
-
(8) 脚本目录:src/main/bin
1.2.4 编码规范
1.2.4.1 包规范
包规范一般包含以下部分,有的团队也在组织内部自定义一个适应于团队的包命名规范。
- (1) 项目基本包:com.company.{项目英文名(较长时适当简化)}.{模块名(可选)}
- (2) config:配置类
- (3) startup:与服务启动相关的类
- (4) client:提供客户端实现的相关类
- (5) common:公共类,定义常量类,通用组件
- (6) entity: 数据库相关的实体类 ,有得使用pojo
- (7) model:数据模型类(参数模型,数据传输模型等) ,有的使用vo
- (8) controller:控制层接口
- (9) service: 服务层
- (10) dao:数据库访问层
- (11) util: 工具类
1.2.4.2 日志记录
系统统一使用SLF4j接口
1.2.4.3 异常处理
一般情况下系统主要处理两类异常:
- (1) 运行时异常:通过参数检查等方式避免或抛出运行时异常,日志记录
- (2) 检查异常:检查异常需要捕获,处理,日志记录
在我们的示例工程代码里,我们定义了以下几个类别的业务异常: - (1) AddOPException:增加操作异常
- (2) ConfigException:配置异常
- (3) DeleteOPException:删除操作异常
- (4) DuplicationException:重复异常
- (5) ModifyPasswordException:修改密码异常
- (6) NoResultException: 没有结果异常
- (7) ParamException:参数异常
- (8) RecoverOPException:覆盖异常
- (9) UpdateOPException:更新异常
异常类一般为RuntimeException,源代代码如下所示:
package com.zone7.demo.helloworld.config.exception;
import com.zone7.demo.helloworld.commons.response.ResponseCode;
import lombok.Data;
/**
* GlobalException
*
* @author: zone7
* @time: 2019.02.14
*/
@Data
public class GlobalException extends RuntimeException {
private ResponseCode responseCode = ResponseCode.ERROR;
public GlobalException() {
}
public GlobalException(String message) {
super(message);
}
public GlobalException(String message, Throwable cause) {
super(message, cause);
}
public GlobalException(Throwable cause) {
super(cause);
}
protected GlobalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
package com.zone7.demo.helloworld.commons.exception;
import com.zone7.demo.helloworld.commons.response.ResponseCode;
import com.zone7.demo.helloworld.config.exception.GlobalException;
import lombok.Data;
/**
* ParamException
*
* @author: zone7
* @time: 2019.02.14
*/
@Data
public class ParamException extends GlobalException {
private ResponseCode responseCode = ResponseCode.ERROR_PARAM_ILLGAL;
public ParamException(String message) {
super(message);
}
}
1.2.4.4 接口定义
-
(1) 原则
- 接口地址定义表明用意
- 接口地址定义清晰,简洁,无歧义
- 同一个服务组件的接口定义具有一致性
-
(2) 格式
- 控制类的顶层地址格式:/{顶层分类名},例如:/sys/user系统管理模块下用户管理相关的接口顶层地址
- 接口定义使用Swagger的API注解说明
- 标注完整的请求信息,请求方法,请求地址,参数可选性,接口描述
-
(3) 请求方式
- GET URL-Params
- POST Form-Data
- POST RequestBody(JSON格式)
- POST Mulitpart
-
(4) 响应方式
- 统一的响应模型
1.2.4.5 辅助工具
- 字符串处理:apache common-lang3
- 时间日期处理:joda-time
- JSON处理:Gson,Fastjson
- 集合扩展工具:guava
- 文件和流处理:commons-io
- 编解码:commons-codec
- 建议:尽可能使用开源组件
1.2.4.6 代码注释
代码注释是
- (1) 类,接口,枚举顶层注释
- (2) 接口方法注释
- (3) 静态方法注释
- (4) 公开方法注释
- (5) 类的属性字段注释
- (6) 常量注释
- (7) 不限于以上
例如:
1.2.4.7 代码控制规范
-
(1) 拉取原则
强制每日开始工作拉取,提交之前拉取。 -
(2) 提交原则
- 强制要求提交代码必须构建成功(编译,打包成功)
- 提交代码必须完整(例如:少提文件)
- 提交代码必须忽略到本地临时文件(例如:target, logs, .idea, *.iml,dist 等)
- 要求每完成一个功能就进行提交
- 每修改完一个Bug就进行提交
- 如有冲突,要求解决冲突完之后才可提交
- 建议每日结束工作提交
- (3) 提交注释
要求提交时使用中文填写注释,注释的内容必须反映本次提交变更情况
注释描述内容需要添加前缀,前缀如下:
- [创建] 通常在项目创建时使用
- [新增]
- [修改]
- [删除]
- [修复-number] 修复Bug使用,number是Bug编号
1.2.4.8 构建规范
- (1) 公共组件构建规范
- (1) 构建输出组件包
- (2) 构建输出组件源码包
- (3) 构建发布到公司私有仓库
- (4) 服务组件构建规范
- (5) 服务组件包命名:{组件名称}-{版本号}-bin.zip
- (6) 构建输出到工程根目录下的target/{组件名称}-{yyyyMMddHH}目录
1.2.5 测试规范
在制定测试规范前,我们先了解下测试的概念。软件测试的对象包括软件需求、概要设计、详细设计、软件运行环境、可运行程序和软件源代码等。软件测试包括质量、人员、资源、技术和流程五大要素,以及测试覆盖率和测试效率两个目标。
软件测试一般分为4个阶段:单元测试、集成测试、系统测试、验收测试。
- (1) 单元测试:测试系统最小可验证单元,发现BUG,确保符合设计要求。单元测试可以通过编写测试代码实现单元测试,也可以使用postman、浏览器等工具测试开发完的模块功能。
- (2) 集成测试:在单元测试的基础上,把软件单元按照软件概要设计规格说明的规格要求,组装成模块、子系统或系统的过程中各部分工作是否达到或实现相应技术指标及要求。集成测试是测试各个单元模块之间的接口,系统测试是测试整个系统的功能和性能;
- (3) 系统测试:将经过集成测试的软件,作为计算机系统的一部分,与系统中其他部分结合起来,在实际运行环境下进行一系列严格有效的测试,以发现软件潜在的问题,保证系统的正常运行。
- (4) 验收测试:也称交付测试,是针对用户需求、业务流程进行的正式的测试,以确定系统是否满足验收标准,由用户、客户或其他授权机构决定是否接受系统。验收测试包括alpha测试和beta测试,alpha测试是由开发者进行的软件测试,beta测试是由用户在脱离开发环境下进行的软件测试。
SpringBoot的测试需要在Pom 添加spring-boot-starter-test和Junit依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
测试类统一放在src/test目录下。