Java开发规范(Cursor版)

工程结构

XXX(工程名)

  • xxx-api: 子工程名,提供给外部调用api包

    • api: 定义提供给外部调用的RPC接口API, 类命名规范需遵循xxxAPI的格式, 如OrderAPI;

      • dto: 接口调用的入参和返参, 入参命名规范为xxxReq, 返参命名规范为xxxDTO, 如OrderDTO;
    • model: 定义一些通用参数,该模型可以被 api包和msg包使用, 命名规范为xxxDTO;

    • msg: 定义消息类的参数, 类命令规范需遵循XxxMsg, 如OrderActionMsg;

  • xxx-app: 子工程名, 服务内部的逻辑实现

    • adapter: 表现层

      • web:

        • controller: 提供给前端的Restful接口, 类命名规范需遵循xxxController, 如OrderCenterController;

          • model: 接口的出入参, 请求参数类命名规范需遵循xxxReq, 如OrderSaveReq, 返参类命名规范需遵循xxxVO, 如OrderProductSaveVO,
        • config: 提供web层的通用配置信息, 如接口的错误切面拦截, 命名规范需遵循xxxAdvice, 如RestCommonExceptionAdvice;

      • api: 提供给外部服务RPC调用的接口, 类命名规范需遵循xxxRpcController, 如OrderRpcController;

      • consumer: mq(如kafka/rocketmq)的消费逻辑, 类命名规范需遵循xxxConsumer, 如ProductToCreateConsumer;

      • job: xjob的执行逻辑, 类命名规范需遵循xxxJob, 如OrderPayCheckJob;

    • app: 应用/流程层, 实现核心业务逻辑, 具体的服务名命名需遵循XxxAppService, 其中前缀为领域名, 如OrderPayAppService;

      • event: 流程事件(消息的发送), 命名需遵循XxxEventProducer, 如OrderEventProducer;
    • config: 提供全局的配置, 命名需遵循XxxConfig;

      • filter: 提供全局的过滤器类型, 命名需遵循XxxFilter;

      • interceptor: 提供全局的拦截器, 命名需遵循XxxInterceptor;

    • infrastructure: 服务的基础设施层

      • acl: 防腐层, 接口命名需遵循XxxAclService的规范, 如UserAclService;

        • impl: 防腐层接口的具体实现, 命名需遵循XxxAclServiceImpl的规范, 如UserAclServiceImpl, 其中对不兼容的外部feign接口的封装, 命名需遵循XxxAclServiceAdapter的规范, 如IUserServiceAdapter;
      • repository: 数据库层, 可包含如mysql/es/redis 等数据库调用;

        • dao: mysql的查询

          • entity: 数据库实体, 类命名需遵循XxxEntity, 其中Xxx为表名的驼峰形式, 如OrderProductEntity;

          • mapper: 命名需遵循XxxMapper, 其中Xxx为表名的驼峰形式, 如OrderProductMapper;

          • service: 基于mybatis-plus设计, dao层的接口,命名需遵循XxxDao, 其中Xxx为表名的驼峰形式, 如OrderProductDao;

            • impl: 基于mybatis-plus设计, 需继承com.baomidou.mybatisplus.extension.service.impl.ServiceImpl并实现dao层的接口, 命名需遵循XxxServiceImpl, 其中Xxx为表名的驼峰形式, 如OrderProductServiceImpl;
        • es: es的查询, 类命名需遵循XxxEsService;

          • model: es索引的数据结构, 命名规范需遵循XxxEO, 如UniOrderEO;
        • redis: redis的查询, 类命名需遵循XxxRedisService, 如ProductRedisService;

    • util: 工具类, 命名需要遵守规范XxxUtil, 如GsonUtil;

注释规范

代码注释

  • 普通类注释(注释后空一行)
/**
类的描述
*
@author xiaoming
@date 2025/5/8 下午5:49
*/
  • Controller类注释,tag带上模块的名称(例如sms-* controller)
@Api(value = "/sms/send", tags = "sms-短信发送 controller")
  • 方法的注释

    • 方法注释中清晰的阐述方法的描述以及所有参数描述;

    • 如果方法注释有变更, 联动修改@date的时间, 如果是新增的类, 使用当前时间;

    • @author需要获取本地git的username, 不能使用无意义的如admin等;

/**
方法的描述
*
@param token 访问授权
@param id ID ID
@return com.gaotu100.common.core.util.AuthToken
@author xiaoming
@date 2025/5/8 下午8:32
*/
  • Req、DTO、VO、Entity注释,注意:

    • 注释均推荐采用ApiDoc形式,对Req和VO, example须添加示例值

    • Req注意增加字段校验, 如果需要的话

@ApiModelProperty(value = "标签名", example = "测试字段")
@NotBlank(message = "标签名不能为空")
@Length(max = 15, message = "标签名最多15个字")
private String label;
  • 值为枚举类型变量注释
/**
@see com.gaotu100.common.core.enums.CampusScopeEnum
*/
@ApiModelProperty(value = "校区范围", example = "1")
private Integer campusScope;

或者

@ApiModelProperty(value = "0-全部校区;1-指定校区;2-直营校区;3-加盟校区", example = "1")
@NotNull(message = "适用校区不能为空")
@EnumValidAnnotation(message = "适用校区类型值错误", allowNull = false, target = CampusScopeEnum.class)
private Integer campusScope;
  • 方法内单行注释
// 加密方式
boolean isAes = "aes".equals(encrypt_type);

类变量注释,禁止使用 “//”

/**
视频上传完成
*/
FILE_UPLOAD_COMPLETE("FileUploadComplete"),
  • 变量多行注释
/**
视频上传完成
视频上传完成
*/
FILE_UPLOAD_COMPLETE("FileUploadComplete"),

Controller规范

  • DTO/VO命名规范为:controller路径 + 方法名 + DTO/VO,例如SmsSendSingleDTO

  • Controller示例方法名如下,

    • page - 分页;pageBy* - 根据某一个条件分页,例如pageByOrg;page* - 分页查询某对象,例如pageOrg

    • list,其他类似page

    • get,其他类似page

    • save,其他类似page

    • update,其他类似page

    • delete,其他类似page

    • 类似bindMa,bind为动词,代表某一具体操作

  • 不使用try/catch

// 示例
@Api(value = "/sms/record", tags = "sms - 短信发送记录 Controller")
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/sms/record")
public class SmsRecordController {
    private final SmsRecordService smsRecordService;
    @PostMapping("/page")
    public R<IPage<SmsRecordPageVO>> page(@Valid @RequestBody SmsRecordPageDTO param) {
        return R.data(smsRecordService.page(param));
    }
}

Util规范

  • 工具类需要以Util后缀结尾

属性文件规范

  • 命名为 *Properties,*的名称同prefix的名称

  • 属性名同配置文件,例如default-stu-appid对应defaultStuAppid

  • 加注释

@Data
@Component
@ConfigurationProperties(prefix = WxMaProperties.PREFIX)
public class WxMaProperties {
    public static final String PREFIX = "wx.ma";
    /**
     * 默认的学生端小程序
     */
    private String defaultStuAppid;
    /**
     * 默认的老师端小程序
     */
    private String defaultTchAppid;
}

VO、DTO规范

  • SysDictPageDTO、SysDictVO中的DTO、VO都是大写,需继承BaseXO

  • 尽量在DTO类中进行参数的校验

  • DTO/VO/Entity类中,不要增加业务逻辑

其他

  • 代码对数据库Entity字段中updateTime、createTime不再进行更新,数据库已做了统一更新;

  • 代码可以使用一些联合查询;

  • Mybatis plus 调用创建、更新、删除api时,只会返回true跟抛异常,不存在false的情况,因此不要使用其返回结果进行判断处理业务逻辑;

  • 单个方法代码行数不能超过80行,过长的方法需要拆分;

  • 代码中避免出现magic number,须为常量或者枚举类型中的值;

  • 所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较,eg:Integer;

  • POJO类中布尔类型的变量,都不要加is,否则部分框架解析会引起序列化错误;

  • 所有的POJO类属性必须使用包装数据类型,RPC方法的返回值和参数必须使用包装数据类型——避免NPE问题

posted @ 2025-05-06 14:02  wangzukun  阅读(328)  评论(0)    收藏  举报