前言

项目需要整理所有依赖的外部Feign调用,整理成一份文档,类似于:

远程接口 调用位置 作用
xxx/zzz top.imyzt.xxx#methodName 用作xxx

方案

因为项目过多,且依赖的外部服务接口众多,不想一个个去整理,故想直接读取所有的Feign接口,直接扫描出方法注释,将上述表格完成。

Java是编译型语言,当代码从.java编译成.class后,代码中的注释将会清空,所以说,项目打包之后,就无法再进行注释的解析了,所以反射等方案不可行,通过在Google搜索,发现了com.sun.tools.javadoc.Main工具类,可以直接读取文件的形式读取.java文件,然后解析其中的各类注释信息,使用起来也很简单,下面举个例子:

/**
 * 类注释
 * @author imyzt
 * @date 2024/04/10
 */
public class Demo {

    /**
     * 方法注释
     */
    public void demo() {

    }
}

上面是一个简单的带注释的类,通过sun公司的工具类,可以直接读取:

public class Doclet {
    public static Logger logger = LoggerFactory.getLogger(Doclet.class);

    private static RootDoc rootDoc;
    private final String clsFilePath;

    public static boolean start(RootDoc root) {
        rootDoc = root;
        return true;
    }

    public Doclet(String clsFilePath) {
        this.clsFilePath = clsFilePath;
    }

    public void exec() {
        com.sun.tools.javadoc.Main.execute(
                new String[]{"-doclet", Doclet.class.getName(),
                        "-docletpath", Doclet.class.getResource("/").getPath(),
                        "-encoding", "utf-8",
                        clsFilePath});
        ClassDoc[] classes = rootDoc.classes();

        if (classes == null || classes.length == 0) {
            logger.warn(clsFilePath + " 无ClassDoc信息");
            return;
        }

        ClassDoc classDoc = classes[0];
        // 获取类的名称
        System.err.println("类名:" + classDoc.name());
        // 获取类的注释
        String classComment = Reflect.on(classDoc).field("documentation").get().toString();
        System.err.println("类注释:" + classComment);
        // 获取属性名称和注释
        for (FieldDoc field : classDoc.fields(false)) {
            System.err.printf("属性名:%s, 属性类型:%s, 注释:%s%n", field.name(), field.type().typeName(), field.commentText());
        }

        for (MethodDoc method : classDoc.methods(false)) {
            System.err.printf("方法名:%s, 方法返回类型:%s, 注释:%s%n", method.name(), method.returnType().typeName(), method.commentText());
        }
    }
}

最终的运行效果:

public class CommentReader {

    public static void main(String[] args) {
        Doclet doclet = new Doclet("/Users/.../java-reader-classormethod-comment/src/main/java/top/imyzt/learing/readercomment/Demo.java");
        doclet.exec();
        // 正在构造 Javadoc 信息...
        // 类名:Demo
        // 类注释: 类注释
        //  @author imyzt
        //  @date 2024/04/10
        //
        // 方法名:demo, 方法返回类型:void, 注释:方法注释
    }
}

通过这个工具类,可以快速的读取,解析各类注释信息,进行资料的整理。
工具类还有很多其他的API,网上资料也很多,这里只是记录做一个备忘,具体的使用时进行Google搜索即可。

示例代码

java-reader-classormethod-comment