java 文档自动生成的神器 idoc
写文档
作为一名开发者,每个人都要写代码。
工作中,几乎每一位开发者都要写文档。
因为工作是人和人的协作,产品要写需求文档,开发要写详细设计文档,接口文档。
可是,作为一个懒人,平时最讨厌的一件事情就是写文档。
写文档最令我不爽的地方是在于代码备注要改一遍,然后文档再改一遍。
所有重复的劳作,都是对于我们宝贵摸鱼时间的最大浪费。
于是,我就常常想,能不能只写一遍呢?
i-doc 项目简介
idoc 为 java 项目生成项目文档。
基于原生的 java 注释,尽可能的生成简介的文档。用户可以自定义自己的模板,生成自己需要的文档。
实现原理:基于 maven 插件,类似于 javadoc。可以更加灵活,允许用户自定义。
特性
(1)基于 maven 项目生成包含大部分信息的元数据
(2)默认支持 markdown 简化文档的生成,支持自定义模板
(3)支持用户自定义文档生成器
(4)支持用户自定生成文档的类过滤器
(5)添加字段类型别名,支持用户自定义
快速入门
需要
jdk1.8+
maven 3.x+
maven 引入
使用 maven 引入当前 idoc 插件。
<build><plugins><plugin><groupId>com.github.houbb</groupId><artifactId>idoc-core</artifactId><version>0.3.0</version></plugin></plugins>
</build>
测试对象的创建
为了演示文档,我们创建了一个 Address 对象。
package com.github.houbb.idoc.test.model;/*** 地址* @author binbin.hou* @since 0.0.1*/
public class Address {/*** 城市*/private String country;/*** 街道*/private String street;public String getCountry() {return country;}public void setCountry(String country) {this.country = country;}public String getStreet() {return street;}public void setStreet(String street) {this.street = street;}
}
执行插件
mvn com.github.houbb:idoc-core:0.3.0:idoc
命令行日志信息
[INFO] ------------------------------------ Start generate doc
[INFO] 共计 【1】 个文件待处理,请耐心等待。进度如下:
==================================================================================================== 100%
[INFO] Generator doc with docGenerator: com.github.houbb.idoc.core.api.generator.ConsoleDocGenerator
[INFO] ------------------------------------ 文档信息如下:[类名] com.github.houbb.idoc.test.model.Address
[类信息] {"comment":"地址","docAnnotationList":[],"docFieldList":[{"comment":"城市","name":"country","type":"java.lang.String"},{"comment":"街道","name":"street","type":"java.lang.String"}],"docMethodList":[{"docMethodParameterList":[],"docMethodReturn":{"fullName":"java.lang.String","name":"String","packageName":"java.lang"},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"getCountry","seeList":[],"signature":"getCountry()"},{"docMethodParameterList":[{"docAnnotationList":[],"name":"country","type":"java.lang.String"}],"docMethodReturn":{},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"setCountry","seeList":[],"signature":"setCountry(country)"},{"docMethodParameterList":[],"docMethodReturn":{"fullName":"java.lang.String","name":"String","packageName":"java.lang"},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"getStreet","seeList":[],"signature":"getStreet()"},{"docMethodParameterList":[{"docAnnotationList":[],"name":"street","type":"java.lang.String"}],"docMethodReturn":{},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"setStreet","seeList":[],"signature":"setStreet(street)"}],"docTagList":[{"lineNum":5,"name":"author","parameters":["binbin.hou"],"value":"binbin.hou"},{"lineNum":6,"name":"since","parameters":["0.0.1"],"value":"0.0.1"}],"fullName":"com.github.houbb.idoc.test.model.Address","modifiers":["public"],"name":"Address","packageName":"com.github.houbb.idoc.test.model"}[INFO] ------------------------------------ Finish generate doc
更多生成方式
当然,你可以发现这里只是把元数据进行输出到控台,意义不大。
我们可以根据需求,自定义实现生成类。
比如下面的方式,可以使用内置的 MarkdownDocGenerator
输出到 markdown 文件。
<plugin><groupId>com.github.houbb</groupId><artifactId>idoc-core</artifactId><version>0.3.0</version><configuration><generates><generate>com.github.houbb.idoc.ftl.api.generator.MarkdownDocGenerator</generate></generates></configuration><dependencies><dependency><groupId>com.github.houbb</groupId><artifactId>idoc-ftl</artifactId><version>0.3.0</version></dependency></dependencies>
</plugin>
效果可以参考:
heaven 文档目录
ps: heaven 项目是个人整理了多年的工具包,几百个类,手写文档估计要很久。
设计初衷
节约时间
Java 文档一直是一个大问题。
很多项目不写文档,即使写文档,对于开发人员来说也是非常痛苦的。
不写文档的缺点自不用多少,手动写文档的缺点也显而易见:
非常浪费时间,而且会出错。
无法保证及时更新。代码已经变了,但是文档还要同步修改。需要强制人来维护这一种一致性。这很难。
为什么不是 swagger-ui
java 的文档有几类:
- jdk 自带的 doc 生成。这个以前实践给别人用过,别人用 C#,看到 java 的默认文档感觉很痛苦。
就算是我们 java 开发者,也很讨厌看 jdk 的文档。看着不美观,也很累。
- swagger-ui 是基于 java 注解的文档生成工具。相对而言比较优雅,也非常强大。
但是缺点也是有的。开发人员要写 jdk 原来的注释+注解。注解太多,导致写起来也很痛苦,大部分开发者后来还是选择了放弃。
那么问题来了?我们怎么办才能尽可能的让开发人员,和文档阅读人员都乐于接受呢?
jdk 自带的 doc 就是基于 maven 插件的,本项目也是。
区别如下:
尽可能的保证和 Java 原生注释一致,让开发者很容易就可以使用。
尽可能的信息全面,但是文档简洁。让文档的阅读者享受到等同于手写文档的体验。
将信息的获取和生成区分开。方便用户自己定义自己的输出方式。
参数配置说明
为了更加灵活的实现文档的生成和文档元数据的生成,提供如下参数
插件配置属性简介
属性 | 是否必填 | 说明 | 默认值 | 备注 |
---|---|---|---|---|
encoding | 否 | 项目编码 | UTF-8 | |
includes | 否 | 元数据包含的文件信息 |
**\/*.java
|
默认扫描所有 java 文件 |
excludes | 否 | 元数据排除的文件信息 | 无 | 默认不排除 |
isOverwriteWhenExists | 否 | 文档存在时是否覆盖 | true | |
isAllInOne | 否 | 所有类信息是否生成单个文档 | true | 命令行文档生成器,此属性无意义。 |
generates | 否 | 文档生成类 | 命令行文档生成信息 |
可以同时指定多个。类名全称。用户自定义参见 com.github.houbb.idoc.api.core.genenrator.IDocGenerator
|
generateFilters | 否 | 文档生成类过滤器 | 无 |
可以同时指定多个。类名全称。用户自定义参见 com.github.houbb.idoc.api.core.filter.IDocGenerateFilter
|
targetDir | 否 | 生成目标文件目录 | 无 | 自定义指定文档生成的文件夹 |
isAllInOne
简单的文档,建议直接生成在一个文件。
如果较为复杂,则可以设为 false,则会按照
generates 相关问题
默认的命令行文档,主要用于演示和信息查看,不具有实际意义。
建议引入 idoc-ftl
模块,使用 MarkdownDocGenerator
生成器。
可以同时指定多个。
可引入 idoc-api
自行定义。
generateFilters 建议
实际的文档,主要关心定义的方法。
我们可以针对 DocClass 的包名,过滤只生成 Service 方法文档。
如果是在以前的基础上,则可以加上 @since
@version
等信息的过滤。
可以同时指定多个。
可引入 idoc-api
自行定义。
自定义 Filter
可以参考当前项目的 idoc-test
模块。
整体配置如下:
<build><plugins><plugin><groupId>com.github.houbb</groupId><artifactId>idoc-core</artifactId><version>0.3.0</version><configuration><isAllInOne>true</isAllInOne><generates><generate>com.github.houbb.idoc.ftl.api.generator.MarkdownDocGenerator</generate></generates><generateFilters><generateFilter>com.github.houbb.idoc.test.filter.MyGenerateFilter</generateFilter></generateFilters></configuration><dependencies><dependency><groupId>com.github.houbb</groupId><artifactId>idoc-test</artifactId><version>${project.version}</version></dependency></dependencies></plugin></plugins>
</build>
指定文档生成器
指定使用 Markdown 文档生成器,可以同时指定多个。
<generates><generate>com.github.houbb.idoc.ftl.api.generator.MarkdownDocGenerator</generate>
</generates>
引入包
MarkdownDocGenerator 在 idoc-ftl
模块中,需要引入对应的依赖。
当然 idoc-core
默认依赖 idoc-ftl
。
指定文件生成类的过滤器
如果不定义自己的类生成过滤器,则会生成所有的类信息。
一般使用中我们只关心 service 方法,所以添加了类的过滤实现。
实现如下:
引入 idoc-api 包
<dependency><groupId>com.github.houbb</groupId><artifactId>idoc-api</artifactId><version>${project.version}</version>
</dependency>
实现 IDocGenerateFilter
package com.github.houbb.idoc.test.filter;import com.github.houbb.idoc.api.core.filter.IDocGenerateFilter;
import com.github.houbb.idoc.api.model.metadata.DocClass;/*** 自定义生成过滤器* @author binbin.hou* @since 0.0.1*/
public class MyGenerateFilter implements IDocGenerateFilter {@Overridepublic boolean include(DocClass docClass) {if("QueryUserService".equalsIgnoreCase(docClass.getName())) {return true;}return false;}}
插件中配置使用
<generateFilters><generateFilter>com.github.houbb.idoc.test.filter.MyGenerateFilter</generateFilter>
</generateFilters>
注意,也需要将你定义这个过滤器的 jar 添加依赖,否则无法找到对应的类信息。
<dependencies><dependency><groupId>com.github.houbb</groupId><artifactId>idoc-test</artifactId><version>${project.version}</version></dependency>
</dependencies>
类代码信息
User 信息
/*** 用户信息* @author binbin.hou* @since 0.0.1*/
public class User {/*** 名称* @require 是* @remark 中文名称,请认真填写*/private String name;/*** 年龄*/private int age;/*** 生日*/private Date birthday;/*** 地址*/private List<Address> addressList;/*** 伴侣*/private User mate;//...
}
i-doc 定义的标签
@require
表示当前字段是否必填,作为方法入参时。
@remark
表示当前字段的备注信息。
方法类信息
- QueryUserService.java
/*** 查询用户服务类* @author binbin.hou* @since 0.0.1*/
public interface QueryUserService {/*** 根据用户信息查询用户* @param user 用户信息* @return 结果* @since 0.0.2,2019/02/12*/public User queryUser(final User user);}
执行插件
mvn com.github.houbb:idoc-core:0.3.0:idoc
- 日志信息
[INFO] ------------------------------------ Start generate doc
[INFO] 共计 【4】 个文件待处理,请耐心等待。进度如下:
==================================================================================================== 100%
[INFO] Generator doc with docGenerator: com.github.houbb.idoc.ftl.api.generator.MarkdownDocGenerator
[INFO] Markdown 生成文档文件 all in one 路径: /Users/houbinbin/code/_github/idoc/idoc-test/src/main/resources/idoc-gen/idoc-test-全部文档.md
[INFO] ------------------------------------ Finish generate doc
文档信息
当前文件路径日志会打印,比如我自己测试的为:
/Users/houbinbin/code/_github/idoc/idoc-test/src/main/resources/idoc-gen/idoc-test-全部文档.md
文档生成效果
参见文档:
idoc-test-全部文档.md
字段类型别名支持
可以参考当前项目的 idoc-test
模块。
为什么需要
有时候页面显示类型,希望更加友好。
所以系统内置了一些别名显示,也同时支持自定义别名。
类型字段的别名
系统内置
系统当前版本提供了常见的别名。
详情见 com.github.houbb.idoc.core.util.JavaTypeAliasUtil
类型 | 别称 |
---|---|
java.lang.Float | 浮点型 |
java.lang.Double | 浮点型 |
java.util.Date | 日期 |
java.time.LocalDateTime | 日期时间 |
java.util.Currency | 货币 |
float | 浮点型 |
java.lang.Integer | 整型 |
long | 长整型 |
java.math.BigDecimal | 数字 |
java.lang.Character | 字符 |
java.lang.Long | 长整型 |
java.lang.Short | 短整型 |
java.util.Map | 映射 |
java.time.LocalTime | 时间 |
java.lang.Boolean | 布尔值 |
java.math.BigInteger | 数字 |
java.lang.String | 字符串 |
java.lang.Byte | 字节 |
double | 浮点型 |
byte | 字节 |
java.util.Collection | 集合 |
int | 整型 |
java.util.List | 列表 |
boolean | 布尔值 |
java.time.LocalDate | 日期 |
char | 字符 |
short | 短整型 |
void | 空 |
array | 数组 |
自定义的方式
可以通过 typeAlias 指定自定义的字段别称。
<configuration><generateFilters><generateFilter>com.github.houbb.idoc.test.filter.MyGenerateFilter</generateFilter></generateFilters><isAllInOne>true</isAllInOne><typeAliases><typeAlias><key>java.lang.String</key><value>String自定义说明</value></typeAlias></typeAliases>
</configuration>
优先级
用户自定义的字段别名优先级高于系统默认。
后面定义的别名会直接覆盖前面的别名。
测试代码演示
对象定义
/*** 别名测试* @author binbin.hou* @since 0.0.1*/
public class TypeAliasSimpleBean {/*** 名称*/private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
测试日志
运行测试日志如下:
{"comment":"别名测试","docAnnotationList":[],"docFieldList":[{"comment":"名称","name":"name","type":"java.lang.String","typeAlias":"String自定义说明"}],"docMethodList":[{"docMethodParameterList":[],"docMethodReturn":{"fullName":"java.lang.String","name":"String","packageName":"java.lang"},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"getName","seeList":[],"signature":"getName()"},{"docMethodParameterList":[{"docAnnotationList":[],"name":"name","type":"java.lang.String","typeAlias":"String自定义说明"}],"docMethodReturn":{},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"setName","seeList":[],"signature":"setName(name)"}],"docTagList":[{"lineNum":5,"name":"author","parameters":["binbin.hou"],"value":"binbin.hou"},{"lineNum":6,"name":"since","parameters":["0.0.1"],"value":"0.0.1"}],"fullName":"com.github.houbb.idoc.test.model.TypeAliasSimpleBean","modifiers":["public"],"name":"TypeAliasSimpleBean","packageName":"com.github.houbb.idoc.test.model"}
其中 typeAlias 就是字段类型的别名,我们可以用来更加友好的显示字段信息。
其他的思考
自定义方式的便利性
自定义的方式采用基于 xml 的方式是比较方便。
但是数量比较多的时候就没有那么方便,本来考虑添加对应的配置属性接口,权衡下还是使用了 xml 配置的方式。
是否使用 comment 信息?
如果一个字段,没有指定别名,是否使用 comment 信息做替代?
建议使用,当前版本不做处理。
- 为什么使用
比起冗长的类信息,大部分人更乐于看到解释。
如果是针对同构的系统(都是 java 语言),则可以理解。
如果是针对异构的系统(比如前台是 php),则不易于理解。
- 为什么不处理
大部分的接口都是常见字段, 性价比不高。
可能存在字段没有些 comment 的情况,会导致判断的复杂性。
如果用户不想使用别名
直接修改模板即可,使用原来的字段 type
属性即可。
开源地址
https://github.com/houbb/idoc
当然,这个项目还有很长的路要走。
如果喜欢,欢迎 fork star~
java 文档自动生成的神器 idoc相关推荐
- Java支持latex,基于Java和LaTeX的文档自动生成技术研究
基于Java和 LaTeX 的文档 自动生成技术研究 ◆尚宝欣 徐 屹 (东北电力大学理学院,吉林 长春 132012) [摘 要]讨论了结合Java与LaTex 自动生成 PDF文档的方法.针 展名 ...
- Java api文档自动生成工具smartdoc+torna
首先,一般做java服务端都用过postman,并且都写过前端调用的api文档接口,并且也用过市面上的一些工具. API自文档动生成,能够省去了写文档的时间. 当然,当前也会有很多类似的开源工具,我们 ...
- Word 2010文档自动生成目录和某页插入页码
一.Word 2010文档自动生成目录 关于Word文档自动生成目录一直是我身边同学们最为难的地方,尤其是毕业论文,经常因为目录问题,被要求修改,而且每次修改完正文后,目录的内容和页码可能都会发生变化 ...
- 基于模板替换的word文档自动生成
简介 word文档自动生成程序是一个根据用户提供的模板word文档以及一些必要的数据文件来渲染生成所要的word文档的工具. 关键词:批量word文档生成.word文档渲染.自动生成word 使用场景 ...
- Java注释详解-Java文档注释生成Java API文档
Java文档注释是一种功能强大的注释形式,如果在你所编写的程序中规范的添加文档注释,那你就可以生成一份系统正规的API文档.Java文档注释 /**文档注释内容*/,注意区分多行注释/*多行注释*/. ...
- java如何生成api文档_api文档自动生成工具
java开发,根据代码自动生成api接口文档工具,支持RESTful风格,今天我们来学一下api-doc的生成 预览 在线预览地址 开发原理 这个工具是一个典型的前后端分离开发的项目,想了解前后端分离 ...
- java poi获取word文档自动生成的序号
POI不能获取word自动生成的序号,但是可以自己根据级别自己写出来. maven <dependency><groupId>org.apache.poi</groupI ...
- 开发工具合集专题《管理工具,DoxygenAPI文档自动生成》
Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,完全支持C.C++.Java.Objective-C和IDL语言,部分支持PHP.C#.注释的语法与Qt-Doc.KDoc和J ...
- php怎么根据接口文档实现功能,CodeIgniter+swagger实现 PHP API接口文档自动生成功能...
一.安装swagger 1.首先需要有composer,没有的自行百度安装 2.下载swagger,打开网站https://packagist.org/packages/zircote/swagger ...
最新文章
- 交换机和路由器各自的实现原理
- 你还在使用 try-catch-finally 关闭资源?不太优雅~
- Tensorflow-gpu在windows系统下的安装及使用(使用Pycharm IDE)
- 面向对象 - 1.面向过程/2.面向对象/3.如何使用类/4.__init__方法/5.属性查找/6.补充知识/7.可扩展性高...
- boost之timer,progress_timer,progress_display的介绍及使用
- unity3d软阴影和硬阴影的原理_Unity3D中两种默认阴影的实现
- 访问nfs_通过NFS访问编年引擎
- linux 没有那个文件或目录_【新视频进度】国庆节至今更新6节quot;嵌入式Linux应用开发基础quot;...
- 监督学习之knn、naive bayes、决策树算法实验_机器学习基本概念
- 理财经理们都想用AI,但客户们不想用 | 福布斯报告
- sql 连接高级语言之后查询出现乱码_还有不会用 SQL 的程序员吗?
- 措施优先级(AP)方法
- 浏览器发送POST请求、DELETE请求
- (Java)输入一个字母,若是小写字母,则变为大写输出,否则,原样输出
- 数据库MSSQLSERVER_18456错误解决
- mysql按天执行分区表sql_Mysql按天自动表分区教程
- TO B革命 读书笔记整理
- 北斗校时系统(GPS授时设备)几种时间同步方法
- lesson-3 photoshop之套索工具,渐变、移动
- Only no-arg methods may be annotated with @Scheduled
热门文章
- 安卓简单app《录音机》实现
- 2023全球最佳医院榜单及简要介绍
- NLP 英文文本数据增强
- KALI LINUX 安装PS画图工具——gimp(超级详细图解)
- 利用电子计算机处理数字化的影像信息,医学影像学 总资料
- 字符串匹配算法---BF及KMP
- HTML怎么样把图片换行,我的css代码如下,为什么读出来的图片每一行只有1个,能不能每行三个,第四个换行_html/css_WEB-ITnose...
- C语言:二进制与十进制相互转换
- 阿里云服务器ECS存储增强通用型g7se实例CPU性能参数详解
- c#作业二: 用C#实现一个记事本