以下是基于业界最佳实践的 SpringBoot 项目命名规范总结,涵盖项目、包、代码及配置文件的命名规则:
一、项目命名规范
项目名称或者模块名称都遵循这个规范:
- 全小写字母
避免操作系统路径兼容性问题(如Linux区分大小写)。 - 连字符分隔单词
使用短横线-
连接多单词(如user-management-system
),禁止使用下划线或空格。 - 描述性明确
直接体现项目功能(如payment-gateway
而非project-001
)。
二、包命名规范
-
反转域名前缀
格式:
com.组织名.项目模块
(如com.example.account
)。 -
全小写字母+点分隔
包名中禁止使用大写字母或连字符(如错误示例:
com.example.userService
)。点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式(如应用工具类包名为
com.alibaba.ei.kunlun.aap.util
) -
分层结构清晰
按功能分层命名子包:
javacom.example.project ├── controller # 请求入口层 ├── service # 业务逻辑层(含impl实现类包) ├── repository # 数据访问层 ├── model # 实体类层 └── config # 配置类包
三、类与接口命名规范
类型 | 命名规则 | 示例 |
---|---|---|
Controller | 名词+Controller |
UserController |
Service接口 | 名词+Service |
OrderService |
Service实现类 | 名词+ServiceImpl |
OrderServiceImpl |
实体类 | 首字母大写的名词 | Product |
配置类 | 名词+Config |
SecurityConfig |
当一个接口有多个实现类时,命名建议采用以下方式:
核心实现类(默认/主要实现): 保持名词+ServiceImpl
命名(如 OrderServiceImpl)
其他实现类: 采用名词+功能描述+Impl
格式,例如:
OrderServiceCacheImpl(带缓存功能的实现) OrderServiceMockImpl(用于测试的Mock实现) OrderServiceAsyncImpl(异步实现版本)
特殊场景:
- 针对不同数据源的实现:OrderServiceJdbcImpl / OrderServiceNoSqlImpl
- 不同算法版本:OrderServiceV1Impl / OrderServiceV2Impl
这种命名方式能清晰体现:
- 实现类与接口的归属关系(通过 Service 后缀)。
- 具体实现的功能差异(通过中间描述词)。
- 避免因简单编号导致的含义模糊问题。
注意事项
- 类名使用 UpperCamelCase 风格,以下情形例外:DO/BO/DTO/VO/AO/PO/UID 等。只包含名词,禁止包含动词,介词或副词。命名时要谨慎考虑类的所在层级或颗粒度,禁止以数据字段的颗粒度单位去命名类。
- 抽象类命名使用 Abstract 或 Base 开头;实现类以 Impl 为后缀;工具类以 Util 为后缀;异常类命名使用 Exception 结尾,测试类命名以它要测试的类的名称开始,以 Test 结尾。枚举类名以Enum为后缀,枚举成员名称需要全大写并以下划线(
_
)分隔。类名如果有复数含义,可以使用复数形式。比如 MessageUtils(此规则参考 spring 的框架结构)。 - 如果模块、接口、类、方法使用了设计模式,在命名时要体现出具体模式。将设计模式体现在名字中,有利于阅读者快速理解架构设计思想。如果有使用模式,则以模式的名称为后缀,例如 Factory,Proxy,Observer 等。比如:public class OrderFactory;
- POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误。表达是与否的数据库字段采用 is_xxx 的命名方式,所以需要在设置从 is_xxx 到 xxx 的映射关系。
- 接口中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁性,并加上有效的 Javadoc 注释。尽量不要在接口里定义常量,如果一定要定义,最好确定该常量与接口的方法相关,并且是整个应用的基础常量。JDK8 中接口允许有默认实现,那么这个 default 方法,是对所有实现类都有价值的默认实现。
- 接口和实现类的命名有两套规则:1)对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,内部的实现类用 Impl 的后缀与接口区别。CacheServiceImpl 实现 CacheService 接口。 2)如果是形容能力的接口名称,取对应的形容词为接口名(通常是 --able 结尾的形容词)。AbstractTranslator 实现 Translatable。
四、方法和变量命名规范
- 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格。方法名参数名采用"动词+名词"的形式。变量名只包含名词,长度不宜过长(单词个数建议不超过4),语义需清晰。方法名过长时某些名词可以采用缩写的形式,但禁止出现语焉不详的情况,例如 XXXHis,XXXCnd 等。
- 常量命名应该全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。常量采用 static 修饰。非专属常量,不使用唯一的一个常量类来维护,按常量功能进行归类与维护。
- 类型与中括号紧挨相连来定义数组。定义整形数组,比如:
int[] arrayDemo
。 - 避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可理解性降低。
- 在常量与变量命名时,表示类型的名词放在词尾,以提升辨识度。startTime / workQueue / nameList / TERMINATED_THREAD_COUNT。
五、配置文件命名规范
-
主配置文件
application.yml
(或.properties
)。 -
多环境配置
通过
-{profile}
后缀区分环境:application-dev.yml
:开发环境application-prod.yml
:生产环境 。
-
日志配置
- Logback:
logback-spring.xml
- Log4j 2.x:
log4j2-spring.xml
(置于src/main/resources/
)。
- Logback:
六、自定义 Starter 命名规范
类型 | 命名模式 | 示例 |
---|---|---|
官方Starter | spring-boot-starter-模块名 |
spring-boot-starter-data-jpa |
自定义Starter | 模块名-spring-boot-starter |
mybatis-spring-boot-starter |
七、接口 API 命名规范
业务 API 接口和 OpenAPI 接口的命名规范都需要遵循 RESTful 设计风格:
- URL 路径命名
小写字母与中划线连接:路径应使用小写字母,单词间用中划线分隔(如/user-profile),避免下划线或驼峰命名。
资源导向:路径需体现资源层级(如/orders/{order-id}/items),避免包含动词,操作由HTTP方法(GET/POST等)体现。
复数形式:资源集合建议使用复数名词(如/users),单个资源可通过路径参数标识(如/users/{id})。
- 版本控制
路径标识版本:推荐在URL中显式声明版本(如/v1/products),便于后续迭代时兼容旧客户端。
避免将版本号混入查询参数或请求头,以保持URL语义清晰。
- 参数命名
查询参数:使用小写蛇形命名(如sort_by=create_time),明确描述过滤、排序等逻辑。
路径参数:需与资源层级匹配(如/departments/{dept-id}),参数名需简洁且无歧义。
- 各层命名规约
A)Service / DAO 层方法命名规约:
1)获取单个对象的方法用 get 做前缀。
2)获取多个对象的方法用 list 做前缀,复数结尾,如:listObjects
3)获取统计值的方法用 count 做前缀。
4)插入的方法用 save / insert 做前缀。
5)删除的方法用 remove / delete 做前缀。
6)修改的方法用 update 做前缀。
B)领域模型命名规约:
1)数据对象:xxxDO,xxx 即为数据表名。
2)数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
3)展示对象:xxxVO,xxx 一般为网页名称。
4)POJO 是 DO / DTO / BO / VO 的统称,禁止命名成 xxxPOJO。
DO / PO / DTO / BO / VO / UID
- DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
- BO(Business Object):业务对象,可以由 Service 层输出的封装业务逻辑的对象。
- Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类来传输。
- VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
八、数据库命名规范
-
数据库表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint(1 表示是,0 表示否)。注意:POJO 类中的任何布尔类型的变量,都不要加 is 前缀,所以,需要在设置从 is_xxx 到 Xxx 的映射关系。数据库表示是与否的值,使用 tinyint 类型,坚持 is_xxx 的命名方式是为了明确其取值含义与取值范围。
说明:任何字段如果为非负数,必须是 unsigned。
正例:表达逻辑删除的字段名 is_deleted,1 表示删除,0 表示未删除。
-
表名、字段名必须使用小写字母或数字,禁止出现数字开头禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。说明:MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库名、表名、字段名,都不允许出现任何大写字母,避免节外生枝。
-
表名不使用复数名词。说明:表名应该仅仅表示表里面的实体内容,不应该表示实体数量,对应于 DO 类名也是单数形式,符合表达习惯。
-
禁用保留字,如 desc、range、match、delayed 等,请参考 MySQL 官方保留字。
-
主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。
说明:pk_即 primary key;uk_即 unique key;idx_即 index 的简称。
-
小数类型为 decimal,禁止使用 float 和 double。说明:在存储的时候,float 和 double 都存在精度损失的问题,很可能在比较值的时候,得到不正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数并分开存储。
-
如果存储的字符串长度几乎相等,使用 char 定长字符串类型。
-
varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引率。
-
表必备三字段:id,create_time,update_time。说明:其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。create_time,update_time 的类型均为 datetime 类型,如果要记录时区信息,那么类型设置为 timestamp。
-
在数据库中不能使用物理删除操作,要使用逻辑删除。
说明:逻辑删除在数据删除后可以追溯到行为操作。不过会使得一些情况下的唯一主键变得不唯一,需要根据情况来酌情解决。
-
表的命名最好是遵循"业务名称_表的作用"。正例:alipay_task / force_project / trade_config / tes_question。
-
库名与应用名称尽量一致。
-
如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。
-
字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:
1)不是频繁修改的字段。
2)不是唯一索引的字段。
3)不是 varchar 超长字段,更不能是 text 字段。
比如各业务线经常冗余存储商品名称,避免查询时需要调用商品服务获取。
-
单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。
-
合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检索速度。
九、其他命名规范
- 所有编程相关的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
- 所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式也要避免采用。
- 代码和注释中都要避免使用任何人类语言中的种族歧视性或侮辱性词语。
- 杜绝完全不规范的英文缩写,避免望文不知义。
- 为了达到代码自解释的目标,任何自定义编程元素在命名时,使用完整的单词组合来表达。