我是靠谱客的博主 斯文玫瑰,最近开发中收集的这篇文章主要介绍【Groovy】编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中进行方法拦截 )一、在 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 name
    def 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 源单元 , 可以通过该对象拿到源文件
     */
    @Override
    void visit(ASTNode[] nodes, SourceUnit source) {
        println nodes
        println source
        println source.AST
        println 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:02_Project12_GroovyGroovy_DemosrcmaingroovyresourcesMETA-INFservicesorg.codehaus.groovy.transform.ASTTransformation 目录层级及文件 , 在文件中配置 ASTTransformation 实现类的全类名 :

MyASTTransformation

在这里插入图片描述


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


首先 , 进入 D:02_Project12_GroovyGroovy_Demosrcmaingroovy 目录 ,

cd D:02_Project12_GroovyGroovy_Demosrcmaingroovy

然后 , 编译 编译时处理类 MyASTTransformation.groovy , 将编译后的字节码文件 MyASTTransformation.class 保存到 D:02_Project12_GroovyGroovy_Demosrcmaingroovyclasses 目录下 ,

groovyc -d classes MyASTTransformation.groovy

再后 , 打包上述编译好的字节码文件 , 存放在 D:02_Project12_GroovyGroovy_Demosrcmaingroovytest.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 name
    def hello(){
        println "hello"
    }
}

def student = new Student()
student.hello()


在这里插入图片描述

最后

以上就是斯文玫瑰为你收集整理的【Groovy】编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中进行方法拦截 )一、在 MyASTTransformation#visit 方法中进行方法拦截二、完整代码示例及进行编译时处理的编译过程的全部内容,希望文章能够帮你解决【Groovy】编译时元编程 ( 编译时方法拦截 | 在 MyASTTransformation#visit 方法中进行方法拦截 )一、在 MyASTTransformation#visit 方法中进行方法拦截二、完整代码示例及进行编译时处理的编译过程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部