【Groovy】MOP 元对象协议与元编程 ( Groovy 类内部和外部分别获取 metaClass | 分析获取 metaClass 操作的字节码 | HandleMetaClass 注入方法 )

简介: 【Groovy】MOP 元对象协议与元编程 ( Groovy 类内部和外部分别获取 metaClass | 分析获取 metaClass 操作的字节码 | HandleMetaClass 注入方法 )

一、Groovy 类内部和外部分别获取 metaClass

在 Groovy 类 内部 和 外部获取的 metaClass 是不同的 ;


代码示例 :

class Student {
    def methodMissing(String name, def args) {
        println metaClass
        return null
    }
}
def student = new Student()
println student.metaClass
student.hello()

打印结果 :

org.codehaus.groovy.runtime.HandleMetaClass@732d0d24[groovy.lang.MetaClassImpl@732d0d24[class Student]]
groovy.lang.MetaClassImpl@732d0d24[class Student]

在 Groovy 脚本中 , 即 Student 外部 , 获取的 student.metaClass 类型是 org.codehaus.groovy.runtime.HandleMetaClass ;


在 Student 对象内部的 methodMissing 方法中 , 获取的 metaClass 类型是 groovy.lang.MetaClassImpl ;


二、分析 Groovy 类内部和外部获取 metaClass 操作的字节码


下面开始分析字节码文件 :


Groovy 脚本的字节码文件内容 :

public class Groovy extends Script {
    public Groovy() {
        CallSite[] var1 = $getCallSiteArray();
        super();
    }
    public Groovy(Binding context) {
        CallSite[] var2 = $getCallSiteArray();
        super(context);
    }
    public static void main(String... args) {
        CallSite[] var1 = $getCallSiteArray();
        var1[0].call(InvokerHelper.class, Groovy.class, args);
    }
    public Object run() {
        CallSite[] var1 = $getCallSiteArray();
        Object student = var1[1].callConstructor(Student.class);
        var1[2].callCurrent(this, var1[3].callGetProperty(student));
        return var1[4].call(student);
    }
}


Student 类字节码文件内容 :

public class Student implements GroovyObject {
    @Generated
    public Student() {
        CallSite[] var1 = $getCallSiteArray();
        super();
        MetaClass var2 = this.$getStaticMetaClass();
        this.metaClass = var2;
    }
    public Object methodMissing(String name, Object args) {
        CallSite[] var3 = $getCallSiteArray();
        var3[0].callCurrent(this, this.metaClass);
        return null;
    }
    @Generated
    @Internal
    public MetaClass getMetaClass() {
        MetaClass var10000 = this.metaClass;
        if (var10000 != null) {
            return var10000;
        } else {
            this.metaClass = this.$getStaticMetaClass();
            return this.metaClass;
        }
    }
    @Generated
    @Internal
    public void setMetaClass(MetaClass var1) {
        this.metaClass = var1;
    }
}


在 Student 类内部获取 metaClass 的语句是

var3[0].callCurrent(this, this.metaClass);

此处直接调用 this.metaClass 获取 metaClass , 而这个 this,metaClass 是构造方法中通过 this.$getStaticMetaClass() 获取的 MetaClass ;

MetaClass var2 = this.$getStaticMetaClass();
        this.metaClass = var2;

在 Student 类外部 ( Groovy 脚本中 ) 获取 metaClass 的语句是

var1[2].callCurrent(this, var1[3].callGetProperty(student));

此处是通过动态调用节点的方式获取 metaClass , 动态获取 student 对象中的属性 ;


不同的调用方式获取的 metaClass 是不同的 ;


三、使用 HandleMetaClass 注入方法


Student 对象内部获取的 groovy.lang.MetaClassImpl , 是不能进行方法注入的 , 注入方法会报错 ;


如果使用 MetaClass 为 Student 类注入方法 , 必须使用 org.codehaus.groovy.runtime.HandleMetaClass 对象进行方法注入 ;


目录
相关文章
|
机器学习/深度学习 人工智能 API
LabVIEW AI开发者福音:LabVIEW OpenVINO AI加速工具包,不来看看?
LabVIEW AI开发者福音:LabVIEW OpenVINO AI加速工具包,不来看看?
556 1
LabVIEW AI开发者福音:LabVIEW OpenVINO AI加速工具包,不来看看?
|
SQL 存储 关系型数据库
MySQL修改表结构到底会不会锁表?
DDL(Data Definition Languages)语句:数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。 常用的语句关键字主要包括 create、drop、alter 等。 DML(Data Manipulation Language)语句:数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性。 常用的语句关键字主要包括 insert、delete、udpate 和 select 等。(增删改查) DCL(Data Control Language)语句:数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了
3069 0
MySQL修改表结构到底会不会锁表?
|
5月前
|
消息中间件 存储 Kafka
RocketMQ实战—4.消息零丢失的方案
本文分析了用户支付完成后未收到红包的问题,深入探讨了RocketMQ事务消息机制的实现原理及其在确保消息零丢失中的作用。首先,通过全链路分析发现消息可能在推送、存储或消费环节丢失。接着,介绍了RocketMQ事务消息机制如何通过half消息、本地事务执行及回调确认来保证消息发送成功,并详细解析了其底层原理,如half消息对消费者不可见、rollback与commit操作等。同时,对比了同步重试方案,指出其在复杂场景下的局限性。
RocketMQ实战—4.消息零丢失的方案
|
6月前
|
SQL 分布式计算 监控
Dataphin 评测报告
作为一名数据开发工程师,我有幸体验了阿里云的Dataphin工具。它提供一站式数据生命周期管理,涵盖采集、建模、治理到使用全流程,显著提升效率。开通试用简单友好,离线管道任务开发通过可视化拖拽组件降低门槛,SQL计算任务实用但调度依赖配置稍复杂。补数据功能出色,即席分析准确,数据分析可视化直观。优点包括全流程覆盖、易用性强、灵活性高;改进建议涉及文档优化、模板丰富度和性能监控增强。总之,Dataphin是构建企业级数据中台的理想选择,值得尝试!
|
存储 机器学习/深度学习 数据可视化
基于Python的数据分组技术:将数据按照1, 2, 3规则分为三个列表
基于Python的数据分组技术:将数据按照1, 2, 3规则分为三个列表
181 1
|
数据采集 机器学习/深度学习 人工智能
Python实现文本情感分析
Python实现文本情感分析
175 1
|
12月前
|
数据采集 机器学习/深度学习 自然语言处理
一文讲懂大模型调优技术
随着AI技术的发展,大模型如GPT系列、BERT等成为推动自然语言处理和计算机视觉领域进步的重要驱动力。然而,大模型的调优过程复杂且资源消耗巨大,对开发者构成严峻挑战。本文旨在全面解析大模型调优的关键技术,涵盖数据预处理、模型架构调整、超参数优化、正则化与泛化能力提升,以及分布式训练与并行优化等内容,为开发者提供系统性的调优指南。
|
Android开发
Android监听蓝牙广播
Android监听蓝牙广播
172 1
|
人工智能 运维 监控
构建高效自动化运维体系:DevOps与AI的融合之路
【5月更文挑战第27天】 在数字化转型的浪潮中,企业IT基础设施日趋复杂,传统的运维模式已难以满足快速迭代和稳定性的双重需求。本文探讨了如何通过整合DevOps理念与人工智能技术,构建一个高效、智能且自动化的运维体系。文章将分析当前运维面临的挑战,介绍DevOps的核心概念及其如何与AI结合来提升运维效率,并展示具体实施策略和预期成效,以期为读者提供一种面向未来的运维优化思路。
|
存储 Ubuntu Linux
ubuntu上配置multipath
ubuntu上配置multipath