文章目录
一、使用 ExpandoMetaClass 进行方法注入
三、完整代码示例
一、使用 ExpandoMetaClass 进行方法注入
在 【Groovy】MOP 元对象协议与元编程 ( 方法注入 | 同时注入普通方法、静态方法、构造方法 ) 博客中 , 使用 MetaClass 注入 普通方法、静态方法、构造方法 , 其底层原理就是通过 ExpandoMetaClass 进行方法注入 ;
我们也可以自己手动实现 ExpandoMetaClass 方法注入过程 ;
如为下面的 Student 类注入方法 ;
class Student { def name; }
首先 , 创建 ExpandoMetaClass 实例对象 ;
def expandoMetaClass = new ExpandoMetaClass(Student)
然后 , 为其注入方法 , 可以注入 普通方法、静态方法、构造方法 ;
// 为 expandoMetaClass 注入普通方法 expandoMetaClass.hello = { println "Hello ${delegate.name}" } // 为 expandoMetaClass 注入普通方法 expandoMetaClass.say = { println "My name is ${delegate.name}" } // 为 expandoMetaClass 注入静态方法 expandoMetaClass.'static'.fun = { println "Class Type : ${delegate}" }
再后 , 需要调用 ExpandoMetaClass 对象的 initialize 初始化方法 ;
// 初始化注入方法 expandoMetaClass.initialize()
最后 , 使用初始化后的 ExpandoMetaClass 对象 , 为
// 替换 Student.metaClass Student.metaClass = expandoMetaClass
这样就手动的实现了 Student 类的方法注入 , 如果想要取消方法注入 , 将 Student.metaClass 置空 , 就回到了初始状态 , 之后就无法调用注入的方法 ;
// 将 Student.metaClass 置空 , 又回到了初始状态 // 之后就无法调用注入的方法 Student.metaClass = null
三、完整代码示例
完整代码示例 :
class Student { def name; } println Student.metaClass // 使用 ExpandoMetaClass 注入方法 def expandoMetaClass = new ExpandoMetaClass(Student) // 为 expandoMetaClass 注入普通方法 expandoMetaClass.hello = { println "Hello ${delegate.name}" } // 为 expandoMetaClass 注入普通方法 expandoMetaClass.say = { println "My name is ${delegate.name}" } // 为 expandoMetaClass 注入静态方法 expandoMetaClass.'static'.fun = { println "Class Type : ${delegate}" } // 为 expandoMetaClass 注入构造方法 expandoMetaClass.constructor = { String str -> new Student(name: str) } // 初始化注入方法 expandoMetaClass.initialize() // 替换 Student.metaClass Student.metaClass = expandoMetaClass println Student.metaClass // 调用注入的静态方法 Student.fun() // 使用注入的构造方法初始化 Student 类 def student = new Student("Tom") // 调用注入的普通方法 student.hello() student.say() // 将 Student.metaClass 置空 , 又回到了初始状态 // 之后就无法调用注入的方法 Student.metaClass = null
执行结果 :
org.codehaus.groovy.runtime.HandleMetaClass@45dd4eda[groovy.lang.MetaClassImpl@45dd4eda[class Student]] groovy.lang.ExpandoMetaClass@670002[class Student] Class Type : class Student Hello Tom My name is Tom