javac AbstractProcessor
2021-03-08 02:32
标签:doc 数据 dal one 模板 abstract substring 截取 ima Annotation Processor是javac的一个工具,它用来在编译时扫描和处理注解,通过Annotation Processor可以获取到注解和被注解类的相关信息,然后根据注解自动生成Java代码,省去了手动编写,提高了编码效率。 在编译的时候动态生成类或者改变类的代码!如: lomock:减少get 和set方法的模板代码生成 mapstruct: 动态生成po vo 互转的Convert类 hibernate-jpamodelge 动态生成PO类的元数据映射,减少操作字段的模板代码 公司内部自己实现了一套基于redis 的CRUD的ORM框架 为了解决以下问题 针对并发场景只操作RO部分字段,优化以下场景的写法导致魔法值过多不易维护问题 参考了hibernate-jpamodelge的实现 1.实现自定义Processor继承AbstractProcessor重写process方法 2.在resource下新增META-INF/services并创建文件javax.annotation.processing.Processor 将自定义的processor的全名称配置进去 然后在其他使用的地方引入这个jar就行了 1.新建一个remote 2.指定mvnDebugger javac AbstractProcessor 标签:doc 数据 dal one 模板 abstract substring 截取 ima 原文地址:https://www.cnblogs.com/LQBlog/p/14208046.html说明
它可以做什么
需求
//保存活动信息
BookingActivitySettingRo bookingActivitySettingRo=new BookingActivitySettingRo();
bookingActivitySettingRo.setId(1L);
bookingActivitySettingRo.setActivityName("哈哈哈");
bookingActivitySettingRedisDao.save(bookingActivitySettingRo);
//查询
bookingActivitySettingRedisDao.findOne(1L);
//批量查询
bookingActivitySettingRedisDao.findByIds(Arrays.asList(1l,2l));
//删除
bookingActivitySettingRedisDao.delete(bookingActivitySettingRo.getId());
//编辑
BookingActivitySettingRo settingRedisDaoOne= bookingActivitySettingRedisDao.findOne(1L);
settingRedisDaoOne.setActivityName("我是修改名字");
bookingActivitySettingRedisDao.save(settingRedisDaoOne);
1.并发编辑操作,只操作指定字段,避免整个ro回填,覆盖了其他线程修改的值
2.并发查询操作,追求性能,RO字段过多,只查询关心部分字段 hmget
基础工程redis版本1.3.0-SNAPSHO,增加了编译时自动生成映射类自定义Processor
/**
* @Project 商品uaa
* @PackageName cn.wine.ms.common.gennerator
* @ClassName RedisRoAbstractProcessor
* @Author qiang.li
* @Date 2020/12/28 1:13 下午
* @Description 用于编译时针对打了RO注解的类 生成key的映射,优化hset等redis操作部分字段写魔法值的问题
*/
@SupportedAnnotationTypes({"cn.wine.base.redis.annotation.Ro"})//你的注解的全名称
@SupportedSourceVersion(SourceVersion.RELEASE_8)//jdk环境为java8
public class RedisRoProcessor extends AbstractProcessor {
/**
* {@inheritDoc}
* @param annotations
* @param roundEnvironment
*/
@Override
public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnvironment) {
//遍历所有打了注解的类
if (!roundEnvironment.processingOver() && annotations.size() != 0) {
Set extends Element> elements = roundEnvironment.getRootElements();
Iterator var4 = elements.iterator();
while (var4.hasNext()) {
Element element = (Element) var4.next();
//只处理打了RO注解的类
if (this.isRoEntity(element)) {
try {
createClass(element);
}catch (Exception e){
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,e.getMessage());
}
}
}
}
return true;
}
/**
* 创建class文件
* @param element
* @throws IOException
*/
public void createClass(Element element) throws IOException {
//获得full类名
String className=(((TypeElement)element).getQualifiedName()).toString();
//获得包名
String metaModelPackage=className.substring(0,className.lastIndexOf("."));
//获得属性元数据
List extends Element> fieldsOfClass = ElementFilter.fieldsIn(element.getEnclosedElements());
//生成classBody
String classBody=generateClassBody(fieldsOfClass);
//用户截取原始类名的startIndex
Integer index=className.lastIndexOf(".")+1;
//获得class名字
String simpleClassName=className.substring(index,className.length());
//新类的className
String newClassName=String.format("%s_",simpleClassName);
//根据名字创建class文件
createFile(newClassName,metaModelPackage,classBody);
}
public void createFile(String genarateClassName,String metaModelPackage,String body) throws IOException {
//生成包名
String generatePackageName = metaModelPackage;
//创建Java 文件
JavaFileObject f =processingEnv.getFiler().createSourceFile(genarateClassName);
try(Writer w = f.openWriter();){
PrintWriter pw = new PrintWriter(w);
pw.println("package " + generatePackageName + ";");
pw.println("\npublic class " + genarateClassName + " { ");
pw.println(body);
pw.println(" }");
pw.flush();
}
}
/**
* 构建class内容
* @param fieldsOfClass
* @return
*/
public String generateClassBody(List extends Element> fieldsOfClass){
StringBuilder body=new StringBuilder();
for(Element element:fieldsOfClass){
body.append(String.format(" public final static String %s=\"%s\";",element.getSimpleName(),element.getSimpleName()));
body.append("\n\n");
}
return body.toString();
}
/**
* 是否是打了RO注解的Entity
* @param element
* @return
*/
private boolean isRoEntity(Element element) {
return containsAnnotation(element, new String[]{"cn.wine.base.redis.annotation.Ro"});
}
/**
* 是否有打了指定注解
* @param element
* @return
*/
public static boolean containsAnnotation(Element element, String... annotations) {
assert element != null;
assert annotations != null;
List
#注:如果搭配jpa和mapstract或者lomack的processr冲突 通过以下类似配置解决
#
如何调试
上一篇:Java抽象类和接口练习
下一篇:Java项目 使用Logback