文章目录

  • 一、在 MyASTTransformation#visit 方法中进行方法拦截
  • 二、完整代码示例及进行编译时处理的编译过程
    • 1、Groovy 脚本 Groovy.groovy
    • 2、ASTTransformation 接口实现 MyASTTransformation.groovy
    • 3、配置 ASTTransformation
    • 3、使用命令行进行编译时处理

一、在 MyASTTransformation#visit 方法中进行方法拦截


在上一篇博客 【Groovy】编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中找到要拦截的方法 ) 中 , 在MyASTTransformation#visit 方法中 , 首先获取了 ModuleNode , 然后查找指定的 ClassNode , 从指定的 ClassNode 中查找对应的 MethodNode 节点 ;

方法拦截主要是在 MethodNode 节点中执行 ; 该 MethodNode 节点对应 Student 类的 hello 方法 ;

根据 【Groovy】编译时元编程 ( 方法拦截时用到的 AST 语法树节点 MethodNode 节点 | MethodNode 节点分析 | MethodNode 节点中的BlockStatement) 博客分析 , MethodNode 节点中封装了 private Statement code; 成员 , 该 code 成员的实际类型是 BlockStatement 类型 ;

public class BlockStatement extends Statement

这里首先将 MethodNode 节点的 code 成员赋值给 BlockStatement , 相当于将 Statement 对象转为 BlockStatement 类型 ;

BlockStatement blockStatement = code

在 BlockStatement 对象中 , 封装了 private List<Statement> statements = new ArrayList<Statement>(); 成员 , 这里面就是该 MethodNode 节点中的方法内容 , 将该集合清空 , 就相当于将方法体清空了 , 实现了方法拦截操作 ;

二、完整代码示例及进行编译时处理的编译过程


1、Groovy 脚本 Groovy.groovy

class Student{def namedef hello(){println "hello"}
}def student = new Student()
student.hello()

2、ASTTransformation 接口实现 MyASTTransformation.groovy

import org.codehaus.groovy.ast.ASTNode
import org.codehaus.groovy.ast.builder.AstBuilder
import org.codehaus.groovy.ast.stmt.BlockStatement
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.ASTTransformation
import org.codehaus.groovy.transform.GroovyASTTransformation@GroovyASTTransformation
class MyASTTransformation implements ASTTransformation {/*** 编译时处理方法* @param nodes AST 抽象语法树节点 , 是 ASTNode 数组类型* @param source 源单元 , 可以通过该对象拿到源文件*/@Overridevoid visit(ASTNode[] nodes, SourceUnit source) {println nodesprintln sourceprintln source.ASTprintln source.source.reader.text// 获取 Groovy.groovy 脚本中的类集合 , 并进行遍历// 在 ModuleNode 中的类节点封装在了如下成员中// List<ClassNode> classes = new LinkedList<ClassNode>();source.AST.classes.find {// 查找名称为 Student 的类// it 是 ClassNode 节点it.name == "Student"}?.methods?.find {// 查找 Student 类下名称为 hello 的方法// it 是 MethodNode 节点it.name == "hello"}?.with {// 找到了 Student 下的 hello 方法// 在 MethodNode 节点下调用// it 就是 MethodNode 节点BlockStatement blockStatement = code// 清空 BlockStatement 中的 List<Statement> statements 成员// 方法拦截清空 , 就不再执行原本的方法// 方法注入不清空 , 会执行原来的方法内容blockStatement.statements.clear()}}
}

3、配置 ASTTransformation

创建 D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy\resources\META-INF\servicesorg.codehaus.groovy.transform.ASTTransformation 目录层级及文件 , 在文件中配置 ASTTransformation 实现类的全类名 :

MyASTTransformation

3、使用命令行进行编译时处理

首先 , 进入 D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy 目录 ,

cd D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy

然后 , 编译 编译时处理类 MyASTTransformation.groovy , 将编译后的字节码文件 MyASTTransformation.class 保存到 D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy\classes 目录下 ,

groovyc -d classes MyASTTransformation.groovy

再后 , 打包上述编译好的字节码文件 , 存放在 D:\002_Project\012_Groovy\Groovy_Demo\src\main\groovy\test.jar 路径 ;

jar -cf test.jar -C classes . -C resources .

最后 , 依赖 test.jar 执行 Groovy.groovy 脚本

groovy -classpath test.jar Groovy.groovy

执行结果为 :

[org.codehaus.groovy.ast.ModuleNode@7d7758be]
org.codehaus.groovy.control.SourceUnit@2bdd8394
org.codehaus.groovy.ast.ModuleNode@7d7758be
class Student{def namedef hello(){println "hello"}
}def student = new Student()
student.hello()

【Groovy】编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中进行方法拦截 )相关推荐

  1. 【Groovy】编译时元编程 ( 编译时方法注入 | 使用 buildFromSpec、buildFromString、buildFromCode 进行方法注入 )

    文章目录 一.在 MyASTTransformation#visit 方法中进行方法注入 1.使用 new AstBuilder().buildFromSpec 进行方法注入 2.使用 new Ast ...

  2. 【Groovy】编译时元编程 ( 编译时元编程引入 | 声明需要编译时处理的类 | 分析 Groovy 类的 AST 语法树 )

    文章目录 一.编译时元编程引入 二.声明需要编译时处理的类 三.分析 Groovy 类的 AST 语法树 一.编译时元编程引入 在之前的 " [Groovy]MOP 元对象协议与元编程 &q ...

  3. 【Groovy】编译时元编程 ( 编译 ASTTransformation | 打包 ASTTransformation 字节码文件 | 编译 Groovy 类同进行编译时处理 )

    文章目录 一.编译 ASTTransformation 二.打包 ASTTransformation 字节码文件 三.编译 Groovy 类同进行编译时处理 一.编译 ASTTransformatio ...

  4. 【Groovy】编译时元编程 ( 编译时处理 ASTTransformation 接口实现 | 配置 ASTTransformation )

    文章目录 一.编译时处理 ASTTransformation 接口实现 二.配置 ASTTransformation 一.编译时处理 ASTTransformation 接口实现 声明 ASTTran ...

  5. 【Groovy】编译时元编程 ( 方法拦截时用到的 AST 语法树节点 MethodNode 节点 | MethodNode 节点分析 | MethodNode 节点中的BlockStatement)

    文章目录 一.方法拦截时用到的 AST 语法树节点 MethodNode 节点 二.MethodNode 节点分析 三.MethodNode 节点中的 BlockStatement 集合 一.方法拦截 ...

  6. 【Groovy】编译时元编程 ( ASTTransformation#visit 方法简介 | org.codehaus.groovy.ast.ModuleNode 脚本节点 )

    文章目录 一.ASTTransformation#visit 方法简介 二.org.codehaus.groovy.ast.ModuleNode 脚本节点 一.ASTTransformation#vi ...

  7. 【Groovy】编译时元编程 ( AST 语法树分析 | ClassNode 根节点 | 方法 Methods 节点 | 字段 Fields 节点 | 属性 Properties 节点 )

    文章目录 一.AST 语法树分析 一.AST 语法树分析 在上一篇博客 [Groovy]编译时元编程 ( 编译时元编程引入 | 声明需要编译时处理的类 | 分析 Groovy 类的 AST 语法树 ) ...

  8. 【Groovy】Groovy 语言特点简介 ( 支持 Java 语法 | 支持 Java 虚拟机 | Groovy 语言是动态语言 | Groovy 扩展 JDK | 编译时元编程 )

    文章目录 一.Groovy 支持 Java 语法 二.Groovy 支持 Java 虚拟机 三.Groovy 语言是 动态语言 四.Groovy 扩展 JDK 五.Groovy 编译时元编程 一.Gr ...

  9. 【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )

    文章目录 一.ASTTransformation#visit 方法中访问 Groovy 类.方法.字段.属性 二.完整代码示例及进行编译时处理的编译过程 1.Groovy 脚本 Groovy.groo ...

最新文章

  1. python自学网站有哪些-小白如何入门Python? 制作一个网站为例
  2. java安全编码指南之:锁的双重检测
  3. Java 12:开关表达式
  4. springmvc项目在启动完成之后执行一次方法_SpringMVC源码分析
  5. Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
  6. gnuTLS 提供的 DTLS-API
  7. media encoder中文2022已上线
  8. 轻量级网页安全漏洞扫描工具-Wapiti
  9. 数据结构课程设计(二)---算术表达式求值
  10. excel抽奖软件作弊_使用Excel下拉列表防止作弊
  11. html播放监控视频教程,使用javascript实现监控视频播放并打印日志
  12. java 设置纸张大小设置_Java读取打印机自定义纸张.
  13. SCTF 2021 | 冰天雪地 极限比拼
  14. latex适量缩小公式符号间距,微调公式长度
  15. Android App 耗电的测试方法
  16. bios显示计算机故障,笔记本电脑BIOS出现故障怎么办 三种常见BIOS故障解决方案...
  17. STM32F103C8T6基于Arduino框架下利用定时器跑RBG灯闪烁
  18. 电容的材质资料/什么cog,x5r y5v等知识
  19. 中国版GDPR《个人信息安全规范》解读:国内企业如何保障信息安全?
  20. Numpy库基础知识与常用方法

热门文章

  1. 【云栖大会】基因计算:解读生命的力量
  2. STM32在定时器中控制步进电机
  3. 黑马vue---8-10、v-cloak、v-text、v-html、v-bind、v-on的基本使用
  4. 【深度学习问题整理】
  5. mysql创建表和数据库
  6. Yii 判断是不是post方式提交的数据
  7. 全方位绕过软WAF攻略
  8. webStorm Linux Ubuntu 中文搜狗输入问题
  9. Delphi调用REST
  10. 《JavaScript高级程序设计 第3版》-学习笔记-1