CGLib MethodInterceptor 接口

本文将介绍 CGLib 的 MethodInterceptor 接口

在 CGLib 中,MethodInterceptor 接口是 Enhancer 回调类型,它用来拦截某个方法,在调用方法前后完成其他操作。熟悉 Spring AOP 面向切面编程的读者应该知道,在 Spring AOP 中支持环绕通知,即在调用方法的前后完成其他操作。其实,Spring AOP 的环绕通知和 CGLib  MethodInterceptor 类似。该回调接口仅仅定义了一个 intercept() 方法,定义如下:

java.lang.Object intercept(java.lang.Object obj, java.lang.reflect.Method method, java.lang.Object[] args, MethodProxy proxy) throws java.lang.Throwable

所有生成的代理方法都调用此方法而不是原始方法。原始方法可以通过使用 Method 对象的正常反射调用,也可以使用 MethodProxy(更快)调用。

参数说明:

  • obj:表示“this”,被增强的对象;

  • method:被调用的方法的 Method 对象;

  • args:参数数组,如果是原始类型,则使用包装类型;

  • proxy:用于调用 super (非截取方法),可以根据需要多次调用;

返回:

返回一个与代理方法签名兼容的任何值。如果代理方法返回值为 void,则此方法将忽略此值。

示例代码

(1)定义被代理对象,代码如下:

/**
 * 被代理的类
 * @author hxstrive.com 2021/12/29
 */
public class HelloWorld {

    public void test(String msg) {
        System.out.println(msg);
    }

}

(2)客户端代码,通过 intercept() 方法的 MethodProxy 对象调用目标方法(即 HelloWorld 的 test() 方法)。代码如下:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

/**
 * 验证 setCallback() 设置 MethodInterceptor 接口
 * @author hxstrive.com 2021/12/31
 */
public class CglibDemo {

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(HelloWorld.class);
        // 你可以认为定义了 MethodInterceptor 拦截器
        // 它拦截所有方法,我们就可以在方法执行前后进行处理
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args,
                                    MethodProxy proxy) throws Throwable {
                System.out.println("call method before");
                // 调通 CGLib 的方法代理对象调用目标方法
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("call method after");
                return result;
            }
        });

        HelloWorld sample = (HelloWorld) enhancer.create();
        sample.test("hello world");
    }

}

运行上面程序,输出如下:

call method before
hello world
call method after

根据上面输出结果,我们可以在执行目标方法前后进行其他任何操作。

业精于勤,荒于嬉。——韩愈《进学解》
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号