GroovyMOP 元对象协议与元编程 ( GroovyObject 接口简介 | MetaClass 简介 | 使用 GroovyObject#invokeMethod 执行类方法 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GroovyMOP 元对象协议与元编程 ( GroovyObject 接口简介 | MetaClass 简介 | 使用 GroovyObject#invokeMethod 执行类方法 )相关的知识,希望对你有一定的参考价值。
文章目录
一、GroovyObject 接口简介
在类中 , 如果没有实现某个 方法 或者 成员属性 , 可以利用 元编程 替换类中的 方法或属性 ;
在编译字节码文件时 , 每个 Groovy 类都会被编译成 GroovyObject 接口对象 ;
/**
* 所有的 Groovy 类都要实现的接口
* <p>
* 在Java世界中使用Groovy对象尤其方便。
*/
public interface GroovyObject
/**
* Invokes the given method.
*
* @param name 要执行的方法名
* @param args 方法调用方法参数
* @return 返回方法执行返回值
*/
@Internal // 标记为内部只是为了向后兼容, e.g. AbstractCallSite.createGroovyObjectGetPropertySite 会检查 `isMarkedInternal`
default Object invokeMethod(String name, Object args)
return getMetaClass().invokeMethod(this, name, args);
/**
* 检索属性值。
*
* @param propertyName 属性名称
* @return 返回查到的属性值
*/
@Internal // 标记为内部只是为了向后兼容, e.g. AbstractCallSite.createGroovyObjectGetPropertySite will check `isMarkedInternal`
default Object getProperty(String propertyName)
return getMetaClass().getProperty(this, propertyName);
/**
* 将给定属性设置为新值。
*
* @param propertyName 设置的属性名
* @param newValue 新属性
*/
@Internal // 标记为内部只是为了向后兼容, e.g. AbstractCallSite.createGroovyObjectGetPropertySite will check `isMarkedInternal`
default void setProperty(String propertyName, Object newValue)
getMetaClass().setProperty(this, propertyName, newValue);
/**
* 返回给定类的元类。
*
* @return 此实例的元类
*/
MetaClass getMetaClass();
/**
* 允许用派生实现替换元类。
*
* @param metaClass 新的元类
*/
void setMetaClass(MetaClass metaClass);
二、MetaClass 简介
MetaClass 元类可以用于实现 元编程 的 方法注入 , 方法拦截 , 合成委托 等操作 ;
/**
* Groovy中的元类定义任何给定Groovy或Java类的行为。
* 元类接口定义了两个部分。
* 客户端 API,它是通过ExtendeMetaObjectProtocol接口
* 和Groovy运行时系统的契约定义的。
*
* 通常,编译器和Groovy运行时引擎与此类上的方法交互,
* 而元类客户端与MetaObjectProtocol接口定义的方法交互
*
* @see MetaClassImpl
* @see groovy.lang.MetaObjectProtocol
*/
public interface MetaClass extends MetaObjectProtocol
三、使用 GroovyObject#invokeMethod 执行类方法
定义一个类 , 在其中定义 hello 方法 , 可以直接调用该方法 , 也可以通过 GroovyObject#invokeMethod 执行该方法 ;
代码示例 :
class Student
def name;
def hello()
println "Hello $name"
def student = new Student(name: "Tom")
// 直接调用 hello 方法
student.hello()
// 通过 GroovyObject#invokeMethod 调用 hello 方法
// 第二个参数是函数参数 , 如果为 void 则传入 null
student.invokeMethod("hello", null)
执行结果 :
Hello Tom
Hello Tom
以上是关于GroovyMOP 元对象协议与元编程 ( GroovyObject 接口简介 | MetaClass 简介 | 使用 GroovyObject#invokeMethod 执行类方法 )的主要内容,如果未能解决你的问题,请参考以下文章
GroovyMOP 元对象协议与元编程 ( 方法注入 | 使用 Category 分类进行方法注入的优缺点 )
GroovyMOP 元对象协议与元编程 ( 方法合成引入 | 类内部获取 HandleMetaClass )
GroovyMOP 元对象协议与元编程 ( 方法注入 | 使用 ExpandoMetaClass 进行方法注入 )
GroovyMOP 元对象协议与元编程 ( 方法注入 | 使用 MetaClass 进行方法注入构造方法 )