【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 重写 MetaClass#invokeMethod 方法拦截 JDK 中已经定义的函数 )

简介: 【Groovy】MOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 重写 MetaClass#invokeMethod 方法拦截 JDK 中已经定义的函数 )

文章目录

一、重写 MetaClass#invokeMethod 方法拦截 JDK 中已经定义的函数

1、被拦截的 String#contains 方法原型

2、JDK 正常用法

3、拦截 String 对象的 contains 函数

4、重写 MetaClass#invokeMethod 方法进行函数拦截





一、重写 MetaClass#invokeMethod 方法拦截 JDK 中已经定义的函数


重写 MetaClass#invokeMethod 方法 , 不仅可以拦截自定义的类中的方法 , 还可以拦截 JDK 中已经定义完毕的方法 ;


如果要拦截 JDK 中的方法 , 肯定不能使用 实现 GroovyInterceptable 接口的方法 , 只能使用重写 MetaClass#invokeMethod 方法进行拦截 ;



此处以 String 类为例 , 拦截其中的 contains 方法 , 查询 String 常量 “Hello World” 中是否包含某个子串 “Hello” ;



1、被拦截的 String#contains 方法原型


被拦截方法原型 :


public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /**
     * 当且仅当此字符串包含指定的字符值序列时,返回true。
     *
     * @param s 要查找的字符串
     * @return 如果字符串中包含要查找的字符串返回 true , 反之返回 false
     * @since 1.5
     */
    public boolean contains(CharSequence s) {
        return indexOf(s.toString()) > -1;
    }
}


2、JDK 正常用法


正常用法 : 使用 JDK 中的 String 类中定义的 contains 方法 , 查询字符串中是否包含指定的子串 ;


def string = "Hello World"


// 查询字符串中是否包含 "Hello" 字符串
def flag = string.contains("Hello")
println flag


执行结果 :


true



3、拦截 String 对象的 contains 函数


为 string.metaClass.contains 赋值一个闭包 , 在闭包中接收 CharSequence s 参数 , 这个参数就是传入的要查找的子串 ;



代码示例 :


def string = "Hello World"
string.metaClass.contains = {
    CharSequence s->
        System.out.println "Is \"$string\" contains \"$s\""
        true
}
// 查询字符串中是否包含 "Hello" 字符串
def flag = string.contains("Hello")
println flag


执行结果 :


Is "Hello World" contains "Hello"
true



4、重写 MetaClass#invokeMethod 方法进行函数拦截


使用下面的方法可以拦截所有的函数 ;


def string = "Hello World"
string.metaClass.invokeMethod = {
    String name, Object args ->
        System.out.println "invokeMethod : Object : $string , Method name : $name , Object args : $args"
        // 方法转发 : 调用 string 对象中的原来的方法
        // 注意此处不能使用 metaClass.invokeMethod 方法调用对象中的方法 , 会导致栈溢出
        // 这里通过 MetaClass#getMetaMethod 获取方法 , 然后执行
        def method = delegate.metaClass.getMetaMethod(name, args)
        // 方法不为空再执行该方法
        if (method != null) {
            method.invoke(delegate, args)
        }
}
// 查询字符串中是否包含 "Hello" 字符串
def flag = string.contains("Hello")
println flag


执行结果 :


invokeMethod : String name : contains , Object args : [Hello]
true


目录
相关文章
|
2月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
27 1
|
4月前
|
存储 Java
构造String问题之在JDK 9及更高版本中,直接访问String对象的coder和value属性,如何实现
构造String问题之在JDK 9及更高版本中,直接访问String对象的coder和value属性,如何实现
|
6月前
|
Java
JDK 1.8 函数接口(收藏用)
JDK 1.8 函数接口(收藏用)
|
7月前
|
安全 Java 开发者
JDK 9:模块化系统——重新定义Java的模块化架构
JDK 9引入了模块化系统,对Java的模块化架构进行了彻底的重新定义。本文将深入探讨模块化系统的原理、优势以及如何在实际开发中应用这一特性。
|
7月前
|
Java 开发者
JDK 21中的记录模式(Record Patterns):简化对象匹配与解构
本文将详细介绍JDK 21中引入的新特性——记录模式(Record Patterns)。记录模式是一种强大的语言特性,它允许开发者在switch表达式中使用简化的语法来匹配和解构记录类型(record types)。本文将解释记录模式的概念、语法、使用场景以及与传统模式匹配的区别,并通过示例代码展示记录模式在实际开发中的应用。
|
7月前
|
存储 前端开发 Java
Java【代码分享 13】前端动态添加一条记后端使用JDK1.8实现map对象根据key的部分值进行分组(将map对象封装成指定entity对象)
Java【代码分享 13】前端动态添加一条记后端使用JDK1.8实现map对象根据key的部分值进行分组(将map对象封装成指定entity对象)
49 0
|
SQL 存储 分布式计算
【Java新特性学习 四】JDK8: 库函数新特性之Optional,Streams,Date/Time API(JSR 310),Base64,并行数组
【Java新特性学习 四】JDK8: 库函数新特性之Optional,Streams,Date/Time API(JSR 310),Base64,并行数组
81 0
|
Java
全网首发:JDK绘制文字:四、绘制文字的具体函数分析
全网首发:JDK绘制文字:四、绘制文字的具体函数分析
100 0
|
Java Linux iOS开发
JNI用C加载JDK产生JVM虚拟机,并运行JAVA类main函数(MACOS/LINUX/WINDOWS)
JNI用C加载JDK产生JVM虚拟机,并运行JAVA类main函数(MACOS/LINUX/WINDOWS)
145 0
|
Java Windows
JDK windows加载字体文件的函数
JDK windows加载字体文件的函数
114 0