当前位置: 首页 > article >正文

进阶注解处理器 processor (三)

序言

该篇主于实战一个简单的 processor,代码备注很详细,如果对运行和语法还有疑问的请先查阅下前面几篇,重复内容此处就不赘述了~

annotation

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface JackLog {
}

processor

import com.jack.annotation.JackLog;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import java.util.Set;/*** @author jack*/
@SupportedAnnotationTypes("com.jack.annotation.JackLog")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class JackLogProcessor extends AbstractProcessor {/*** 抽象语法树对象*/private JavacTrees trees;/*** 用于创建语法树节点的所有方法*/private TreeMaker treeMaker;/*** 用于创建标识符*/private Names names;private JavacElements elementUtils;@Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);this.trees = JavacTrees.instance(processingEnv);Context context = ((JavacProcessingEnvironment) processingEnv).getContext();this.treeMaker = TreeMaker.instance(context);this.names = Names.instance(context);elementUtils = (JavacElements) processingEnv.getElementUtils();}@Overridepublic boolean process(Set<? extends TypeElement> annotations,RoundEnvironment roundEnv) {Set<? extends Element> set = roundEnv.getElementsAnnotatedWith(JackLog.class);set.forEach(element -> {JCTree jcTree = trees.getTree(element);jcTree.accept(new TreeTranslator() {@Overridepublic void visitMethodDef(JCTree.JCMethodDecl jcMethodDecl) {doOperationMethod(jcMethodDecl);super.visitMethodDef(jcMethodDecl);}});});return true;}private void doOperationMethod(JCTree.JCMethodDecl jcMethodDecl) {treeMaker.pos = jcMethodDecl.pos;jcMethodDecl.body = treeMaker.Block(0, List.of(getSentenceOne(),jcMethodDecl.body,getSentenceTwo()));}private JCTree.JCStatement getSentenceOne() {Name systemName = elementUtils.getName("System");Name currentTimeMillisName = elementUtils.getName("currentTimeMillis");Name longName = elementUtils.getName("Long");// 拼接 System.currentTimeMillis()JCTree.JCFieldAccess s1 = treeMaker.Select(treeMaker.Ident(systemName),currentTimeMillisName);treeMaker.Exec(treeMaker.Apply(List.nil(), s1, List.nil()));// java.lang.Long fStart = System.currentTimeMillis()return treeMaker.VarDef(treeMaker.Modifiers(0),names.fromString("fStart"), treeMaker.Ident(longName),treeMaker.Apply(List.nil(), s1, List.nil()));}private JCTree.JCStatement getSentenceTwo() {Name systemName = elementUtils.getName("System");Name currentTimeMillisName = elementUtils.getName("currentTimeMillis");Name outName = elementUtils.getName("out");Name printlnName = elementUtils.getName("println");// 拼接 System.outJCTree.JCFieldAccess s1 = treeMaker.Select(treeMaker.Ident(systemName), outName);// 拼接 System.out.printlnJCTree.JCFieldAccess s2 = treeMaker.Select(s1, printlnName);// 拼接 System.currentTimeMillis()JCTree.JCFieldAccess s3 = treeMaker.Select(treeMaker.Ident(systemName),currentTimeMillisName);// 拼接 System.currentTimeMills() - fStartJCTree.JCBinary s4 = treeMaker.Binary(JCTree.Tag.MINUS,treeMaker.Apply(List.nil(), s3, List.nil()),treeMaker.Ident(names.fromString("fStart")));JCTree.JCBinary s5 = treeMaker.Binary(JCTree.Tag.PLUS,treeMaker.Literal("耗时:"), s4);JCTree.JCBinary s6 = treeMaker.Binary(JCTree.Tag.PLUS, s5,treeMaker.Literal("ms"));// System.out.println("耗时:" + (System.currentTimeMills() - fStart) + "ms)return treeMaker.Exec(treeMaker.Apply(List.nil(), s2, List.of(s6)));}
}

配置文件

javax.annotation.processing.Processor

com.jack.processor.JackLogProcessor

结语

第一个自定义 processor 的实战,后续逐步进阶~

如果您看到了这里,欢迎和我沟通交流!
             一个95后码农

个人博客:fy-blog

http://www.lryc.cn/news/2415173.html

相关文章:

  • IP、子网、超网(CIDR)、网段知识讲解
  • ixp协议服务器,ipx协议中的“内部网络号”是什么意思?
  • C语言—strcpy,strncpy函数介绍、以及自己实现字符串的拷贝代码演示
  • 深度剖析 Go 的 nil
  • 什么是哈希算法sha2?和sha1什么区别?SHA2代码签名?sha3又是什么?
  • Linux C语言运行库 glibc
  • YOLOv5输入端(一)—— Mosaic数据增强|CSDN创作打卡
  • AS2安全基础知识
  • JPEG文件格式分析及举例验证
  • 使用CCProxy代理局域网上网
  • GCD详解,多种
  • 缠中说禅:缠非缠、禅非禅,枯木龙吟照大千(整理版)
  • pm2常用命令及pm2自启动
  • rollup - 构建原理及简易实现
  • Java 中正则表达式的详解
  • STM32开发(五)STM32F103 通信 —— CAN通信编程详解
  • mysql instr使用
  • ubuntu新手教程(从安装系统到驱动安装到环境搭建)
  • Kotlin-简约之美-进阶篇(十六):DSL原理解析
  • 一个完整的http协议中都包含什么?
  • SQLServer附加数据库5120错误
  • 快速剖析贪心算法(C语言)
  • MVC介绍
  • android xvideo app,xvideo downloader and player
  • 大数据入门系列 3:全网最全,Ubuntu 安装 VMware Tools 完整步骤及需要注意的问题_ubuntu中怎么检测vmware tools是否安装好
  • makefile基础知识
  • JDK安装配置教程(保姆级)
  • 【ViT系列(2)】ViT(Vision Transformer)代码超详细解读(Pytorch)
  • OPC基本知识介绍——什么是OPC
  • Tornado介绍