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 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号