【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 使用 MetaClass 进行方法拦截 | 对象上拦截方法 | 类上拦截方法 )

简介: 【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 使用 MetaClass 进行方法拦截 | 对象上拦截方法 | 类上拦截方法 )

文章目录

一、使用 MetaClass 进行方法拦截

1、使用 MetaClass 在单个对象上进行方法拦截

2、使用 MetaClass 在类上进行方法拦截

二、完整代码示例

1、对象方法拦截

2、类方法拦截





一、使用 MetaClass 进行方法拦截


MetaClass 可以定义类的行为 , 可以利用 MetaClass 进行方法拦截 ;


Groovy 对象 和 类 都可以获取 MetaClass 对象 , 声明 Srudent 类 , 以及创建 Student 对象 ,


class Student{
    def name;
    def hello() {
        System.out.println "Hello ${name}"
    }
}
def student = new Student(name: "Tom")


1、使用 MetaClass 在单个对象上进行方法拦截


在 Groovy 对象上获取的元类对象 ,


student.metaClass



拦截 MetaClass 上的方法 , 使用


元类对象名.方法名 = {闭包}


即可拦截指定的方法 , 如下拦截 Student student 对象的 hello 方法 :


student.metaClass.hello = {
    println "Hello student.metaClass.hello"
}


执行 hello 方法时 , 执行的是闭包的内容 , 不再是原来的 hello 方法内容 ;



2、使用 MetaClass 在类上进行方法拦截


在 Groovy 类上获取的元类对象 ,


Student.metaClass


拦截 MetaClass 上的方法 , 使用


元类对象名.方法名 = {闭包}

元类对象名.方法名 = {闭包}


进行拦截 , 拦截 MetaClass 类上的方法 , 如 :


// 拦截 student 对象上的方法
Student.metaClass.hello = {
    println "Hello student.metaClass.hello"
}


特别注意 : 必须在创建对象之前 , 拦截指定的方法 , 在创建对象之后拦截 , 没有任何效果 ;






二、完整代码示例



1、对象方法拦截


创建 2 22 个 Student 对象 , 使用 MetaClass 在其中一个对象上拦截 hello 方法 , 执行两个对象的 hello 方法 , 只有前者的 hello 方法被拦截 ;


代码示例 :


class Student{
    def name;
    def hello() {
        System.out.println "Hello ${name}"
    }
}
def student = new Student(name: "Tom")
def student2 = new Student(name: "Jerry")
// Groovy 对象上获取的元类对象
student.metaClass
// Groovy 类上获取的元类
Student.metaClass
// 拦截 student 对象上的方法
student.metaClass.hello = {
    println "Hello student.metaClass.hello"
}
// 直接调用 hello 方法
student.hello()
student2.hello()


执行结果 :


Hello student.metaClass.hello
Hello Jerry




2、类方法拦截


创建 2 22 个 Student 对象 , 使用 MetaClass 在类上拦截 hello 方法 , 执行两个对象的 hello 方法 , 两个对象的 hello 方法都被拦截 ;



特别注意 : 必须在创建对象之前 , 拦截指定的方法 , 在创建对象之后拦截 , 没有任何效果 ;



代码示例 :


class Student{
    def name;
    def hello() {
        System.out.println "Hello ${name}"
    }
}
// 拦截 student 对象上的方法
// 特别注意 : 必须在创建对象之前拦截方法
//           创建对象之后再拦截方法 , 没有效果
Student.metaClass.hello = {
    println "Hello student.metaClass.hello"
}
def student = new Student(name: "Tom")
def student2 = new Student(name: "Jerry")
// Groovy 对象上获取的元类对象
student.metaClass
// Groovy 类上获取的元类
Student.metaClass
// 直接调用 hello 方法
student.hello()
student2.hello()


执行结果 :


Hello student.metaClass.hello
Hello student.metaClass.hello

image.png

目录
相关文章
|
11月前
|
前端开发 C# Windows
解决Gradle下载缓慢的问题,将-bin改为-all
【11月更文挑战第15天】PropertyGrid 是一种用户界面组件,允许用户直观地查看和编辑对象属性。WPF 中虽无内置控件,但可通过组合 Expander 和 DataGrid 实现基本功能,或使用 PropertyTools 等第三方库获得更强大的功能。
238 1
|
12月前
|
前端开发 UED
长轮询(Long Polling)的缺点有哪些?
【10月更文挑战第8天】
347 2
|
Web App开发 JavaScript 前端开发
不光好上手,功能还特强的 Vue 3组件!且开源免费!
不光好上手,功能还特强的 Vue 3组件!且开源免费!
|
12月前
哪些情况可能会导致 try-catch 语句不捕获异常?
【10月更文挑战第12天】在实际应用中,可能还会存在其他一些情况导致异常不被捕获。因此,在使用`try-catch`语句时,需要仔细考虑各种可能的情况,以确保异常能够被正确地捕获和处理。
1194 56
|
11月前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
811 2
|
12月前
|
Java Spring
Gradle 如何确保依赖的版本兼容性
Gradle 通过依赖管理机制确保版本兼容性,使用声明式配置定义项目依赖,自动解析和下载所需库。它支持版本范围和动态版本,通过冲突解决策略选择最佳版本,保证构建的一致性和可靠性。
1023 3
|
NoSQL 关系型数据库 MySQL
Linux搭建mysql以及Redis环境
Linux搭建mysql以及Redis环境
|
存储 前端开发 安全
深入理解React中的useState:函数组件状态管理的利器
深入理解React中的useState:函数组件状态管理的利器
|
API 数据库 Swift
【Swift开发专栏】Swift中的数据持久化:Core Data与Realm
【4月更文挑战第30天】本文探讨了Swift中两种流行的数据持久化框架——Core Data和Realm。数据持久化是保持应用数据在不同运行周期间一致性的关键。Core Data,苹果的ORM系统,适合处理复杂数据关系,提供与iOS生态系统的无缝集成。使用Core Data涉及定义数据模型、生成NSManagedObject子类、配置持久化容器及执行数据操作。而 Realm,一个轻量级数据库,以其高性能、易于使用的API和实时数据同步适用于跨平台项目。在Swift中使用Realm,需定义数据模型、配置Realm实例、执行数据操作并观察数据变化。理解这两者能帮助开发者构建更高效、可靠的应用。
409 0