如何获取java类中的属性注释
作者:小时候的阳光
获取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 + '}'; } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。