1.思路:通过文件操作,在编译前将//的文本描述提取出来,放到新文件的自定义注解的value里边,自定义注解要支持runtime,这样,在运行后通过注解将对应的值拿出来
2.代码:
package cn.togeek.util; import cn.togeek.util.ano.Decorate; import java.io.*; import java.lang.reflect.Field; /** * 工具类,用来在编译前将注释提取成Anotation格式,这里统一用@Decorate */ public class AnotationSepUtil { public static void generateAnotation(String javaFile) throws IOException { File file = new File(javaFile); String parent = javaFile.substring(0,javaFile.lastIndexOf(File.separator)); String temp = parent.concat(File.separator).concat(file.getName()).concat(".tmp"); //String dec = Decorate.class.getResource("Decorate.class").toString().replace("file:/",""); String dec = Decorate.class.getPackage().toString().replace("package ","").concat(".Decorate"); File file1 = new File(temp); if (file1.exists()) { file1.delete(); file1.createNewFile(); } if (file.exists()) { try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file1)); BufferedReader bufferedReader = new BufferedReader(new FileReader(file));) { String s = null; boolean canInsert = false; while ((s = bufferedReader.readLine()) != null) { String toAppend = ""; if(s.isEmpty()) continue; if (canInsert) { bufferedWriter.write("import ".concat(dec).concat("; ")); canInsert = false; } if (s.contains("package ")) { canInsert = true; } if (s.contains("//")) { String[] split = s.split("//"); for (int i=0;i<split[0].length();i++) { char c = split[0].charAt(i); if (Character.isSpaceChar(c)) { toAppend = toAppend.concat(String.valueOf(c)); } else { break; } } toAppend = toAppend.concat("@Decorate(value="").concat(split[1]).concat("") "); toAppend = toAppend.concat(split[0]).concat(" "); } else { toAppend = s.concat(" "); } bufferedWriter.write(toAppend); } } } file.delete(); file1.renameTo(file); } public static void main(String[] args) throws IOException { //AnotationSepUtil.generateAnotation("D:\ideaWorkspace\contract\src\main\java\cn\togeek\service\contract\Contract.java"); } }
3.Decorate.java
package cn.togeek.util.ano; import java.lang.annotation.*; /** * 自定义注解,用于注释解析 */ @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Decorate { public String value(); }
4.执行后的类:
package cn.togeek.service.contract; import cn.togeek.util.ano.Decorate; import cn.togeek.domain.ResponseModle; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.time.YearMonth; import java.util.Date; import java.util.List; import java.util.Map; public class Contract { @Data @Builder @NoArgsConstructor @AllArgsConstructor public static class ContractSD implements IContract{ @Decorate(value="公司名称") private List orgName; @Decorate(value="代理开始时间") private Map agencyStartDate; @Decorate(value="代理结束时间") private Map agencyEndDate; @Decorate(value="所属电厂") private Map belongName; @Decorate(value="所属组织") private Map belongGroup; @Decorate(value="已签约年份") private Map signedYear; @Decorate(value="微信签约客户") private Map wechartUser; @Decorate(value="合同起始日期") private Map htksrq; @Decorate(value="合同截止日期") private Map htjsrq; @Decorate(value="年预计用电量") private ResponseModle nyjydl; @Decorate(value="年双边用电量") private ResponseModle nsbdl; @Decorate(value="购电一项价格") private ResponseModle gdyxjg; @Decorate(value="最终价格") private ResponseModle zzjg; @Decorate(value="考核奖励电价") private ResponseModle khjldj; @Decorate(value="考核奖励最大值") private ResponseModle khjldjMax; @Decorate(value="考核奖励最小值") private ResponseModle khjldjMin; @Decorate(value="额外优惠") private Map ewyh; @Decorate(value="套餐标准价格") private ResponseModle tcbzjg; @Decorate(value="再次签约年份") private Map signYearOnceMore; @Decorate(value="分解电量") private Map fjdl; @Decorate(value="社会信用代码") private Map shxydm; @Decorate(value="企业地址") private Map address; @Decorate(value="企业省市") private Map province; @Decorate(value="企业地区") private Map city; @Decorate(value="企业区县") private Map county; @Decorate(value="开户名称") private Map khmc; @Decorate(value="开户银行") private Map khyh; @Decorate(value="开户账号") private Map khzh; @Decorate(value="联系人") private Map lxr; @Decorate(value="手机号") private Map phone; @Decorate(value="通讯地址") private Map contactAddr; @Decorate(value="乙方售电公司") private ResponseModle yfsdgs; @Decorate(value="乙方地址") private ResponseModle yfdz; @Decorate(value="乙方信用代码") private ResponseModle yfxydm; @Decorate(value="乙方电话") private ResponseModle yfdh; @Decorate(value="乙方法人") private ResponseModle yffr; @Decorate(value="法人") private Map fr; } @Data @Builder @NoArgsConstructor @AllArgsConstructor public static class ContractJJ implements IContract { @Decorate(value="居间合同乙方地址") private Map jjhtYfAddress; @Decorate(value="居间合同乙方法人") private Map jjhtYfFr; @Decorate(value="居间合同乙方电话") private Map jjhtYfTel; @Decorate(value="居间合同乙方传真") private Map jjhtYfFax; @Decorate(value="居间合同乙方社会信用代码") private Map jjhtYfShxydm; @Decorate(value="居间合同甲方") private ResponseModle jjhtJf; @Decorate(value="居间合同甲方地址") private ResponseModle jjhtJfAddress; @Decorate(value="居间合同甲方法人") private ResponseModle jjhtJfFr; @Decorate(value="居间合同甲方电话") private ResponseModle jjhtJfTel; @Decorate(value="居间合同甲方传真") private ResponseModle jjhtJfFax; @Decorate(value="居间合同甲方社会信用代码") private ResponseModle jjhtJfShxydm; } @Data static class DecompositionElectricity{ YearMonth time; Map value; } }
5.获取注解:
private String getAnotation(String field) { try { Field fields = type==ContractType.SD? Contract.ContractSD.class.getDeclaredField(field): Contract.ContractJJ.class.getDeclaredField(field); fields.setAccessible(true); if (fields.isAnnotationPresent(Decorate.class)) { Decorate annotation = fields.getAnnotation(Decorate.class); return annotation.value(); } }catch (Exception e) { e.printStackTrace(); } return ""; }