获取java类中的注释

一般我们的某个数据库表对象model,java bean对象如下:

package com.xxx.message.model;

import com.middol.common.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

/**
 * 邮件等消息发送历史表
 *
 * @author xxxx
 */
@Entity
@Table(name = "T_messageHistory")
@Data
@EqualsAndHashCode(callSuper=true)
public class MessageHistory extends BaseModel {

    /**
     * 工厂id
     */
    @Column(name = "factoryId")
    private String factoryId;

    /**
     * 原有的 messageId
     */
    @Column(name = "messageId")
    private String messageId;

    /**
     * 接收方
     */
    @Column(name = "receiver")
    private String receiver;

    /**
     * 抄送方
     */
    @Column(name = "copy")
    private String copy;

    /**
     * 标题
     */
    @Column(name = "subject")
    private String subject;

    /**
     * 内容
     */
    @Column(name = "content", columnDefinition = "nvarchar(2000)")
    private String content;

    /**
     * 发送类型
     */
    @Column(name = "sendType")
    private String sendType;
}

特殊情况下我们可能需要获取这个类的属性注释,比如JPA生成的表没有注释,我们希望通过java类中的属性注释来更新一下表中字段注释。

这里可以通过jdk自带的 tools.jar工具包进行获取,主要类似于生成javadoc文档那样。
pom.xml文件中导入:

<dependency>
    <groupId>com.sun</groupId>
    <artifactId>tools</artifactId>
    <version>1.8</version>
    <scope>system</scope>
    <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>

systemPath 可以指向磁盘具体的路径,tools.jar一般在 JAVA_HOM/lib 下。

具体测试类如下:

package com.xxx.doc;

import cn.hutool.core.util.ReflectUtil;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.RootDoc;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * 获取某一个java文件代码中属性对应的注释
 *
 * @author guzt
 */
public class Doclet {

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

    private static RootDoc rootDoc;
    private String javaBeanFilePath;

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

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

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

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

        List<FildEntry> entrys = Lists.newArrayList();
        ClassDoc classDoc = classes[0];
        // 获取类的名称
        modelClassDocVO.setModelClassName(classDoc.name());
        // 获取类的注释
        String classComment = ReflectUtil.getFieldValue(classDoc, "documentation").toString();
        String spitStr = "\n";
        for (String msg : classComment.split(spitStr)) {
            if (!msg.trim().startsWith("@") && msg.trim().length() > 0) {
                modelClassDocVO.setModelCommentText(msg);
                break;
            }
        }
        // 获取属性名称和注释
        FieldDoc[] fields = classDoc.fields(false);
        for (FieldDoc field : fields) {
            entrys.add(new FildEntry(field.name(), field.type().typeName(), field.commentText()));
        }

        modelClassDocVO.setFildEntryList(entrys);
        return modelClassDocVO;
    }

     // 测试一下
    public static void main(String[] args) {
        Doclet doclet = new Doclet(
                "E:\\IDEA_HOME\\middol\\parent\\message\\src\\main\\java\\com\\middol\\message\\model\\MessageHistory.java");
        ModelClassDocVO modelClassDocVO = doclet.exec();
        logger.info("类注释:" + modelClassDocVO.getModelCommentText());
        logger.info("属性字段注释如下:");
        modelClassDocVO.getFildEntryList().forEach(System.out::println);
    }
}

测试结果如下:

14:09:23.867 [main] INFO com.middol.doc.Doclet - 类注释: 邮件等消息发送历史表
14:09:23.871 [main] INFO com.middol.doc.Doclet - 属性字段注释如下:
Entry{fName='factoryId', fType='String', fExplain='工厂id'}
Entry{fName='messageId', fType='String', fExplain='原有的 messageId'}
Entry{fName='receiver', fType='String', fExplain='接收方'}
Entry{fName='copy', fType='String', fExplain='抄送方'}
Entry{fName='subject', fType='String', fExplain='标题'}
Entry{fName='content', fType='String', fExplain='内容'}
Entry{fName='sendType', fType='String', fExplain='发送类型'}

上述测试类需要用到的 POJO对象如下:

package com.xxx.doc;

/**
 * 属性字段对应注释
 *
 * @author guzt
 */
public class FildEntry {

    /**
     * 参数名
     */
    private String fName;
    /**
     * 类型
     */
    private String fType;
    /**
     * 说明
     */
    private String fExplain;

    public FildEntry(String fName, String fType, String fExplain) {
        super();
        this.fName = fName;
        this.fType = fType;
        this.fExplain = fExplain;
    }

    @Override
    public String toString() {
        return "Entry{" +
                "fName='" + fName + '\'' +
                ", fType='" + fType + '\'' +
                ", fExplain='" + fExplain + '\'' +
                '}';
    }

    public String getfName() {
        return fName;
    }

    public void setfName(String fName) {
        this.fName = fName;
    }

    public String getfType() {
        return fType;
    }

    public void setfType(String fType) {
        this.fType = fType;
    }

    public String getfExplain() {
        return fExplain;
    }

    public void setfExplain(String fExplain) {
        this.fExplain = fExplain;
    }
}
package com.xxx.doc;

import java.util.List;

/**
 * model 类字段注释
 * @author guzt
 */
public class ModelClassDocVO {


    private String modelTableName;

    private String modelClassName;

    private String modelCommentText;

    private List<FildEntry> fildEntryList;


    public String getModelTableName() {
        return modelTableName;
    }

    public void setModelTableName(String modelTableName) {
        this.modelTableName = modelTableName;
    }

    public String getModelClassName() {
        return modelClassName;
    }

    public void setModelClassName(String modelClassName) {
        this.modelClassName = modelClassName;
    }

    public String getModelCommentText() {
        return modelCommentText;
    }

    public void setModelCommentText(String modelCommentText) {
        this.modelCommentText = modelCommentText;
    }

    public List<FildEntry> getFildEntryList() {
        return fildEntryList;
    }

    public void setFildEntryList(List<FildEntry> fildEntryList) {
        this.fildEntryList = fildEntryList;
    }

    @Override
    public String toString() {
        return "ModelClassDocVO{" +
                "modelClassName='" + modelClassName + '\'' +
                ", modelCommentText='" + modelCommentText + '\'' +
                ", fildEntryList=" + fildEntryList +
                '}';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值