如何获取java类中的属性注释

 更新时间:2024年09月27日 08:58:02   作者:小时候的阳光  
在开发中,有时需要获取Java类的属性注释,尤其是当JPA生成的表缺少注释时,可以通过jdk自带的tools.jar工具包来实现,方法类似于生成javadoc文档,需要在pom.xml文件中导入tools.jar的依赖,该jar文件一般位于JAVA_HOME/lib目录下

获取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>
            <scope>system</scope>
            <systemPath>${project.basedir}/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 +
                '}';
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java中的this、super、final关键字详解

    Java中的this、super、final关键字详解

    这篇文章主要介绍了Java中的this、super、final关键字详解,它在方法内部使用,表示这个方法所属对象的引用,它在构造器内部使用,表示该构造器正在初始化的对象,this 可以调用类的属性、方法和构造器,需要的朋友可以参考下
    2023-09-09
  • Java使用JDBC连接数据库的实现方法

    Java使用JDBC连接数据库的实现方法

    这篇文章主要介绍了Java使用JDBC连接数据库的实现方法,包括了详细的加载步骤以及完整实现示例,需要的朋友可以参考下
    2014-09-09
  • SpringBoot事件发布和监听详解

    SpringBoot事件发布和监听详解

    今天去官网查看spring boot资料时,在特性中看见了系统的事件及监听章节,所以下面这篇文章主要给大家介绍了关于SpringBoot事件发布和监听的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2021-11-11
  • java设计模式之简单工厂模式简述

    java设计模式之简单工厂模式简述

    这篇文章主要为大家详细介绍了java设计模式之简单工厂模式,简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类的实例,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • JAVA语言编程格式高级规范

    JAVA语言编程格式高级规范

    这篇文章主要介绍了JAVA语言编程格式高级规范,需要的朋友可以参考下
    2015-05-05
  • MyBatis数据脱敏的实现方案介绍

    MyBatis数据脱敏的实现方案介绍

    在我们数据库中有些时候会保存一些用户的敏感信息,比如:手机号、银行卡等信息,如果这些信息以明文的方式保存,那么是不安全的
    2022-08-08
  • Java最简洁数据结构之冒泡排序快速理解

    Java最简洁数据结构之冒泡排序快速理解

    冒泡排序是编程中数据结构绕不过的一个基础点,有关于冒泡排序的文章也有很多,但可能会比较缭乱未能理解,本章将一子u为简洁明了的例图带你通关冒泡排序
    2021-11-11
  • Java将字符串转化为数组的两种方法

    Java将字符串转化为数组的两种方法

    Java中的String类是一种特殊的字符串,它可以被用于处理字符串,Java中的String类也可以将字符串转换为数组,下面这篇文章主要给大家介绍了关于Java将字符串转化为数组的两种方法,需要的朋友可以参考下
    2023-05-05
  • idea解决程序包不存在报错的八种解决方法

    idea解决程序包不存在报错的八种解决方法

    这篇文章主要介绍了idea解决程序包不存在报错的八种解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-02-02
  • Java微信公众平台之消息管理

    Java微信公众平台之消息管理

    这篇文章主要为大家详细介绍了Java微信公众平台之消息管理的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05

最新评论