【Groovy】MOP 元对象协议与元编程 ( 方法注入 | 同时注入普通方法、静态方法、构造方法 )

简介: 【Groovy】MOP 元对象协议与元编程 ( 方法注入 | 同时注入普通方法、静态方法、构造方法 )

一、同时注入普通方法、静态方法、构造方法


如果要同时为 Groovy 类注入大量方法 , 使用 Category 分类 或 MetaClass 将每个方法逐个注入 , 这样操作比较繁琐 ;


同时为 Groovy 类注入多个方法 , 可以使用 metaClass 方法实现 , 该函数的原型如下 :

public static MetaClass metaClass(Class self, Closure closure) {
        MetaClassRegistry metaClassRegistry = GroovySystem.getMetaClassRegistry();
        MetaClass mc = metaClassRegistry.getMetaClass(self);
        if (mc instanceof ExpandoMetaClass) {
            ((ExpandoMetaClass)mc).define(closure);
            return mc;
        } else if (mc instanceof DelegatingMetaClass && ((DelegatingMetaClass)mc).getAdaptee() instanceof ExpandoMetaClass) {
            ((ExpandoMetaClass)((DelegatingMetaClass)mc).getAdaptee()).define(closure);
            return mc;
        } else if (mc instanceof DelegatingMetaClass && ((DelegatingMetaClass)mc).getAdaptee().getClass() == MetaClassImpl.class) {
            ExpandoMetaClass emc = new ExpandoMetaClass(self, false, true);
            emc.initialize();
            emc.define(closure);
            ((DelegatingMetaClass)mc).setAdaptee(emc);
            return mc;
        } else if (mc.getClass() == MetaClassImpl.class) {
            MetaClass mc = new ExpandoMetaClass(self, false, true);
            mc.initialize();
            ((ExpandoMetaClass)mc).define(closure);
            metaClassRegistry.setMetaClass(self, mc);
            return mc;
        } else {
            throw new GroovyRuntimeException("Can't add methods to custom meta class " + mc);
        }
    }

使用规则如下 :

类名.mateClass {
  // 注入普通方法
  普通方法名 = {闭包}
  // 注入静态方法
  'static' {
  静态方法名 = {闭包}
  }
    // 注入构造方法
    constructor = {
        构造方法参数列表 ->
          构造方法内容
            要返回的实例对象
    }
}

为下面的 Student 类 , 同时注入 普通方法、静态方法、构造方法 ;

class Student {
    def name;
}

注入方法如下 :

// 注入多个类型的方法
Student.metaClass {
    // 注入普通方法
    hello = {
        println "Hello ${delegate.name}"
    }
    // 注入普通方法
    say = {
        println "My name is ${delegate.name}"
    }
    // 注入静态方法
    'static' {
        fun = {
            println "Class Type : ${delegate}"
        }
    }
    // 注入构造方法
    constructor = {
        String str ->
            new Student(name: str)
    }
}

二、完整代码示例


完整代码示例 :

class Student {
    def name;
}
// 注入多个类型的方法
Student.metaClass {
    // 注入普通方法
    hello = {
        println "Hello ${delegate.name}"
    }
    // 注入普通方法
    say = {
        println "My name is ${delegate.name}"
    }
    // 注入静态方法
    'static' {
        fun = {
            println "Class Type : ${delegate}"
        }
    }
    // 注入构造方法
    constructor = {
        String str ->
            new Student(name: str)
    }
}
// 调用注入的静态方法
Student.fun()
// 使用注入的构造方法初始化 Student 类
def student = new Student("Tom")
// 调用注入的普通方法
student.hello()
student.say()

执行结果 :

Class Type : class Student
Hello Tom
My name is Tom

image.png

image.png

目录
相关文章
|
存储 设计模式 消息中间件
京东二面:为什么Netty要造FastThreadLocal?
FastThreadLocal 从字面意义上来看,它是“Fast”+“ThreadLocal”的结合体,寓意为快速的 ThreadLocal。那么,问题来了,Netty 为什么要再造一个 FastThreadLocal?FastThreadLocal 运行快的原因是啥?除了快之外,它还有其他优势吗? ## 1.先从ThreadLocal说起 ThreadLocal 线程本地变量,每个线程都拥有一份该变量的独立副本,即使是在多线程环境下,每个线程也只能修改和访问自己的那份副本,从而避免了线程安全问题,实现了线程间的隔离。 ThreadLocal 底层是使用 ThreadLocalMap 实现
150 0
京东二面:为什么Netty要造FastThreadLocal?
|
6月前
|
XML 缓存 Java
一文讲透程序编排的核心方式:从表达式语言到并行化实践
高德的poi数据来源多种多样,处理流程也多种多样,但因流程相对固定,因此使用了流程化配置简化开发,使用表达式语言保证灵活性。为了加深对平台的理解,并帮助大家对编排有一定的了解,本文会以影响范围的视角去总结当前编排的方案。
337 13
一文讲透程序编排的核心方式:从表达式语言到并行化实践
|
11月前
|
JSON Java Maven
SpringBoot整合gRPC踩坑回顾
本文回顾了作者在引入gRPC过程中遇到的挑战与解决方案。首先,由于SpringBoot 3.0暂不支持相关starter,导致初期预研不足,项目无法启动。接着,在编写代码时因对微服务架构理解不清,出现多个设计错误。最后,解决依赖冲突问题,特别是`protobuf-java-util`与现有依赖的冲突,通过Maven Helper插件有效排查并修复问题。此次经历加深了作者对微服务架构的理解,并为后续项目拆分打下基础。
520 2
|
数据采集 JavaScript 前端开发
如何使用Python爬虫处理JavaScript动态加载的内容?
如何使用Python爬虫处理JavaScript动态加载的内容?
|
监控 Java 数据库
Java程序如何进行不停机更新?
Java程序如何进行不停机更新?
465 1
|
安全 前端开发 JavaScript
利用HTTP协议进行文件上传和下载的常见方法
【10月更文挑战第25天】可以利用HTTP协议方便地实现文件的上传和下载功能,满足不同应用场景下的需求。在实际应用中,还可以根据具体的业务需求和安全要求,对文件上传和下载的过程进行进一步的优化和安全处理。
|
Java 开发者 API
使用Groovy探索动态语言编程的魅力
【6月更文挑战第6天】Groovy,一种运行在JVM上的动态语言,融合了Java的全部功能与动态语言的便利性。其动态特性包括:动态类型(运行时确定变量类型)、动态方法调用(使用字符串作为方法名)和动态脚本执行(运行时加载执行脚本)。Groovy适用于简化配置、构建DSL和实现灵活插件系统,提供高效开发体验。通过Groovy,开发者能更好地发掘动态编程的魅力。
|
程序员 编译器 C语言
C语言----动态内存分配(malloc calloc relloc free)超全知识点
C语言----动态内存分配(malloc calloc relloc free)超全知识点
1728 6
|
负载均衡 前端开发 Java
Feign 踩坑指南 (接口返回泛型设置属性为null)
Feign 简介 Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。
2634 0
Feign 踩坑指南 (接口返回泛型设置属性为null)
|
Java 开发工具 C++
(2023版本)GraalVM+native-image+Visual Studio 在Win10上全流程安装,避坑+实操
(2023版本)GraalVM+native-image+Visual Studio 在Win10上全流程安装,避坑+实操
1034 1
(2023版本)GraalVM+native-image+Visual Studio 在Win10上全流程安装,避坑+实操

热门文章

最新文章