【Groovy】编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中进行方法拦截 )
文章目录
- 一、在 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 方法中进行方法拦截 )相关推荐
- 【Groovy】编译时元编程 ( 编译时方法注入 | 使用 buildFromSpec、buildFromString、buildFromCode 进行方法注入 )
文章目录 一.在 MyASTTransformation#visit 方法中进行方法注入 1.使用 new AstBuilder().buildFromSpec 进行方法注入 2.使用 new Ast ...
- 【Groovy】编译时元编程 ( 编译时元编程引入 | 声明需要编译时处理的类 | 分析 Groovy 类的 AST 语法树 )
文章目录 一.编译时元编程引入 二.声明需要编译时处理的类 三.分析 Groovy 类的 AST 语法树 一.编译时元编程引入 在之前的 " [Groovy]MOP 元对象协议与元编程 &q ...
- 【Groovy】编译时元编程 ( 编译 ASTTransformation | 打包 ASTTransformation 字节码文件 | 编译 Groovy 类同进行编译时处理 )
文章目录 一.编译 ASTTransformation 二.打包 ASTTransformation 字节码文件 三.编译 Groovy 类同进行编译时处理 一.编译 ASTTransformatio ...
- 【Groovy】编译时元编程 ( 编译时处理 ASTTransformation 接口实现 | 配置 ASTTransformation )
文章目录 一.编译时处理 ASTTransformation 接口实现 二.配置 ASTTransformation 一.编译时处理 ASTTransformation 接口实现 声明 ASTTran ...
- 【Groovy】编译时元编程 ( 方法拦截时用到的 AST 语法树节点 MethodNode 节点 | MethodNode 节点分析 | MethodNode 节点中的BlockStatement)
文章目录 一.方法拦截时用到的 AST 语法树节点 MethodNode 节点 二.MethodNode 节点分析 三.MethodNode 节点中的 BlockStatement 集合 一.方法拦截 ...
- 【Groovy】编译时元编程 ( ASTTransformation#visit 方法简介 | org.codehaus.groovy.ast.ModuleNode 脚本节点 )
文章目录 一.ASTTransformation#visit 方法简介 二.org.codehaus.groovy.ast.ModuleNode 脚本节点 一.ASTTransformation#vi ...
- 【Groovy】编译时元编程 ( AST 语法树分析 | ClassNode 根节点 | 方法 Methods 节点 | 字段 Fields 节点 | 属性 Properties 节点 )
文章目录 一.AST 语法树分析 一.AST 语法树分析 在上一篇博客 [Groovy]编译时元编程 ( 编译时元编程引入 | 声明需要编译时处理的类 | 分析 Groovy 类的 AST 语法树 ) ...
- 【Groovy】Groovy 语言特点简介 ( 支持 Java 语法 | 支持 Java 虚拟机 | Groovy 语言是动态语言 | Groovy 扩展 JDK | 编译时元编程 )
文章目录 一.Groovy 支持 Java 语法 二.Groovy 支持 Java 虚拟机 三.Groovy 语言是 动态语言 四.Groovy 扩展 JDK 五.Groovy 编译时元编程 一.Gr ...
- 【Groovy】编译时元编程 ( ASTTransformation#visit 方法中访问 Groovy 类、方法、字段、属性 | 完整代码示例及进行编译时处理的编译过程 )
文章目录 一.ASTTransformation#visit 方法中访问 Groovy 类.方法.字段.属性 二.完整代码示例及进行编译时处理的编译过程 1.Groovy 脚本 Groovy.groo ...
最新文章
- python自学网站有哪些-小白如何入门Python? 制作一个网站为例
- java安全编码指南之:锁的双重检测
- Java 12:开关表达式
- springmvc项目在启动完成之后执行一次方法_SpringMVC源码分析
- Android中使用HttpURLConnection实现GET POST JSON数据与下载图片
- gnuTLS 提供的 DTLS-API
- media encoder中文2022已上线
- 轻量级网页安全漏洞扫描工具-Wapiti
- 数据结构课程设计(二)---算术表达式求值
- excel抽奖软件作弊_使用Excel下拉列表防止作弊
- html播放监控视频教程,使用javascript实现监控视频播放并打印日志
- java 设置纸张大小设置_Java读取打印机自定义纸张.
- SCTF 2021 | 冰天雪地 极限比拼
- latex适量缩小公式符号间距,微调公式长度
- Android App 耗电的测试方法
- bios显示计算机故障,笔记本电脑BIOS出现故障怎么办 三种常见BIOS故障解决方案...
- STM32F103C8T6基于Arduino框架下利用定时器跑RBG灯闪烁
- 电容的材质资料/什么cog,x5r y5v等知识
- 中国版GDPR《个人信息安全规范》解读:国内企业如何保障信息安全?
- Numpy库基础知识与常用方法