⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7286750827896029199 「雪中亮」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

下面是一个普通的Request类,先简单的看一下:

/**
* TestRequest desc
*/
@Data
@Slf4j
public class TestRequest {
private String name;
private Integer age;
private Address address;
/**
* address desc
*/
@Setter
@Getter
public static class Address {
private String country;
private String province;
private String city;
}
}

因为公司的要求,我们需要使用Protobuff完成序列化工作,并且需要生成API文档,所以我们一般需要补上Swagger注解和Tag注解。为了补上这两种注解,你需要一点一点地敲键盘了。

稍微思考一下就会发现,补充Swagger注解的方法,一般是将相关POJO中同名字段的JavaDoc复制过来,改为Swagger注解的格式即可,而补充Tag注解更简单了,就是无脑的对字段按顺序进行编号,只要保证编号的顺序是递增的且不重复即可。

很明显,上述工作是重复、单调、乏味、无聊、机械的,一切重复、单调、乏味、无聊、机械的工作都可以解放出来,下面直接给出解决方案,使用文字+图片解释太单薄了,直接给出动图:

当然了,这个功能不止可以操作普通的POJO类,Controller类也是可以处理的:

简单来说,我写了一个IDEA插件,在需要添加/删除Swagger注解、Tag注解、JavaDoc注释方面,能够明显提效,尽可能将大家从重复、单调、乏味、无聊的工作中解放出来。

快速开始

想要获得这个插件很简单,打开 Jetbrains Marketplace 的插件页面,直接下载、安装即可:

https://plugins.jetbrains.com/plugin/22348-bitkylin-universal-generate

当然了,直接打开 IntelliJ IDEA 进入Settings -> Plugins -> Marketplace,搜索 Bitkylin Universal Generate 也能够找到。

安装后,记得进入 Settings -> Tools -> Bitkylin Universal Generate,将语言切换到中文(插件考虑到了国际化,所以默认英文哦😉)。

插件的基本用法,上面的动图中略微展示了一下,不过动图中只展示了两个功能。打开右键菜单后可以看到,新增了好几个功能哦,他们都是做什么的呢?

核心功能

你可以通过右键菜单,一键生成Swagger注解:@Api, @ApiOperation, @ApiModel, @ApiModelProperty,一键生成Protostuff注解:@Tag。

全局生成注解的最佳实践,就是上面的动图中演示的那样,除了上面列出的全局一键生成注解外,还是有一些扩展功能,下面系统介绍一下插件的核心功能。

对整个文档处理,统一生成注释、注解

就像上面两张动图中演示的那样,我们随意打开右键菜单,可以看到选项说明中,作用范围是整个文档,此时执行各个功能时,会对整个文档中的所有元素进行处理。

可以对指定字段单独生成注释、注解

除了对整个文档统一处理外,你也可以对单个字段进行处理,比如还是对上面列出的那个POJO类进行操作。首先将光标指向某个字段名,打开右键菜单,此时插件功能全都变更为了对当前字段进行处理。依次进行如下操作:

  • 删除JavaDoc注释
  • 删除刚刚生成的Swagger注解
  • 填充JavaDoc注释
  • 填充Swagger注解

整个操作行云流水~~~

当然我承认,手动删除一个字段的JavaDoc注释、注解,比使用插件删除效率更高。。。但是如果要删除整个类中所有的JavaDoc注释、注解,还是使用插件效率更高:

除了对POJO类中的字段进行操作外,也可以将光标指向Controller类的方法、类名,指向POJO类的类名,选择相应的功能即可对指定的元素进行处理。

将API层的POJO类转换为Service层的POJO类

因为我们需要生成API文档,我们需要使用Protobuff完成序列化工作,所以我们一般需要在API层的POJO类上补充Swagger注解和Tag注解,但是Service层的POJO类不需要这些注解,最多只需要填充JavaDoc注释即可。

考虑这样一个场景:我们和二方对接时,拿到了一个二方API,为了对API进行隔离,我们可以将二方API中定义的Request、Response类复制一份在Service层自己用,可以考虑下面的操作:

  • 将POJO类中的Swagger注解转换为JavaDoc注释
  • 删除POJO类中的所有Swagger、Tag注解

这些操作同样是上面说的重复、单调、乏味、无聊、机械的工作,同样可以使用插件一键完成。上面演示了一大堆令人眼花缭乱的功能,我们打开右键菜单梳理一下,插件提供的四个选项中,除了「注解转JavaDoc」外,都演示过了。那么很显然,这个场景涉及到的就是「注解转JavaDoc」这个功能。

我们使用「注解转JavaDoc」功能,对整个文档一键处理,直接看动图:

使用插件可以一键优雅完成,如果手动做的话,那是真的浪费生命了!

功能释义

上面演示了插件的核心功能,如果仅仅看动图的话,肯定会有很多疑惑的,这一小节尽可能的解释各个功能及其原理。

删除元素

这个功能有四个子选项,可以自由选择要删除的元素哦。一键删除整个文档中的注释、注解,其实还是很好用的。

插件在展示选项前,会检测当前项目是否有swagger、protostuff依赖,如果没有相关依赖,相关选项也是没有的哦。

生成注解

上面演示的最多的就是这个功能,该功能会在Controller类相关元素上添加@Api、@ApiOperation注解,会在POJO类的相关元素上添加@ApiModel、@ApiModelProperty、@Tag注解。

目前标注@Controller、@RestController注解的类,或类名以Controller结尾的类,会被识别为Controller类。标注@Data、@Getter、@Setter注解的类,会被识别为POJO类。如果大家有更好的识别Controller类和POJO类的方法可以留言😁。

值得一提的是,@Tag注解中的序号,会根据字段所处位置的不同,进行动态填充哦,原则是尽可能保证有序、唯一。

注解转JavaDoc

核心用法是,上面重点介绍的「将API层的POJO类转换为Service层的POJO类」场景,该功能做了以下事情:

  • 将Swagger注解中的value字段值提取出来,转换为JavaDoc注释
  • 删除POJO类中的所有Swagger、Tag注解

查找JavaDoc

该功能用于给无任何注释、注解的字段,添加JavaDoc注释。那么问题来了,JavaDoc注释是从哪来的呢?

首先不是由AI生成的,因为AI生成的文本不一定符合语义,并且较为缓慢,成本还高,需要联网,因为有上述缺点所以废弃了该方案。其次不是将字段文本使用各种「翻译」工具翻译过来的,因为翻译功能同样有不符合语义,较为缓慢,成本高,需要联网的缺点。然而插件中该功能的特点是,语义尽可能精确、速度快、不用联网,这是怎么做到的呢?

首先则怎么才能做到语义精确呢?自然是你曾经使用过这个字段,并且标注过这个字段的含义。你在使用IntelliJ IDEA打开一个Project时,IDEA会对该Project中的各个单词、文件名、文件类型等各种元素生成索引。

为什么IDEA中的搜索功能能够快速找到指定的元素,就是这些索引的功劳,当然索引不只能IDEA自己用,我们开发的插件也能用,具体可以参考Jetbrains的官方文档:

https://plugins.jetbrains.com/docs/intellij/file-based-indexes.html#implementing-a-file-based-index

当你对某个字段使用「查找JavaDoc」功能时,插件会检索到项目中的所有同名字段,通过精确或模糊匹配的方式,将所有相关的字段全都检索出来,然后把他们的JavaDoc注释全都提取出来,去重、输出就可以了。实际原理还是很简单的,过程看起来繁琐,但是执行效率极高哦,我监控过耗时,大概率不会超过1毫秒。

「填充」和「重新生成」的区别

插件中每个功能都有多个选项,填充、重新生成、合并,他们有什么区别呢?

  • 填充: 当前「类、字段、方法」中已经存在指定的「注解、注释」时,不会再重新生成相应的「注解、注释」。
  • 重新生成: 不管当前「类、字段、方法」中是否已经存在指定的「注解、注释」,会将已存在的「注解、注释」直接删除,然后再重新生成相应的「注解、注释」。
  • 合并: 当前「类、字段、方法」中如果已经存在指定的JavaDoc注释,还是会重新生成新的JavaDoc注释,并将其合并到原先的JavaDoc中一起展示,新、老JavaDoc注释都会保留哦。
文章目录
  1. 1. 快速开始
  2. 2. 核心功能
    1. 2.0.0.1. 对整个文档处理,统一生成注释、注解
    2. 2.0.0.2. 可以对指定字段单独生成注释、注解
    3. 2.0.0.3. 将API层的POJO类转换为Service层的POJO类
  • 3. 功能释义
    1. 3.0.0.1. 删除元素
    2. 3.0.0.2. 生成注解
    3. 3.0.0.3. 注解转JavaDoc
    4. 3.0.0.4. 查找JavaDoc
    5. 3.0.0.5. 「填充」和「重新生成」的区别