【Groovy】MOP 元对象协议与元编程 ( 方法合成引入 | 类内部获取 HandleMetaClass )

2023-03-30 11:01:47 浏览数 (1)

文章目录

  • 一、方法合成引入
  • 二、类内部获取 HandleMetaClass

一、方法合成引入


在 Groovy 类中 , 如果实现了 GroovyInterceptable 接口 , 调用该 Groovy 类的任何方法都会回调 invokeMethod 方法 , 参考 【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 实现 GroovyInterceptable 接口 | 重写 invokeMethod 方法 ) 博客 ;

如果没有实现 GroovyInterceptable 接口 , 如果调用对象上不存在的方法 , 会回调 methodMissing 函数 , 参考 【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 属性缺失 propertyMissing 函数回调 | 方法缺失 methodMissing 函数回调 ) 博客 ;

利用 Groovy 类的上述特性 , 结合 Expando 动态类 , 实现方法的动态注入 ;

Expando 动态类参考 【Groovy】MOP 元对象协议与元编程 ( Expando 动态类 | 创建动态类 | 为动态类增加字段和方法 ) 博客 ;

假如调用了 Groovy 类不存在的方法 , 那么创建一个新的方法 , 注入到 Groovy 类中 , 这种方法注入方式就是 " 方法合成 " ;

二、类内部获取 HandleMetaClass


注入方法时 , 不能直接在类中使用 metaClass 直接获取 MetaClass , 参考 【Groovy】MOP 元对象协议与元编程 ( Groovy 类内部和外部分别获取 metaClass | 分析获取 metaClass 操作的字节码 | HandleMetaClass 注入方法 ) 博客 , 在类内部获取的 metaClass 类型是 groovy.lang.MetaClassImpl , 该 MetaClass 不能用于方法注入 ;

必须使用 org.codehaus.groovy.runtime.HandleMetaClass 才能进行方法注入 ;

在类内部 , 可以先获取 this 对象 , 先将 this 赋值给 Student 对象变量 , 然后通过 Student 对象获取 metaClass , 此时获取的 MetaClass 就是 org.codehaus.groovy.runtime.HandleMetaClass ;

代码语言:javascript复制
class Student {
    def methodMissing(String name, def args) {
        // 直接获取 metaClass
        println metaClass

        // 先将 this 赋值给 Student 变量
        // 然后通过 Student 对象获取 metaClass
        Student student = this
        println student.metaClass

        return null
    }
}

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

执行结果 :

代码语言:javascript复制
groovy.lang.MetaClassImpl@161b062a[class Student]
org.codehaus.groovy.runtime.HandleMetaClass@161b062a[groovy.lang.MetaClassImpl@161b062a[class Student]]

0 人点赞