Java动态代理总结

动态代理

动态代理就是在程序运行期间,直接通过反射生成一个代理对象,代理对象所属的类是不需要存在的。

1. JDK的基于接口的动态代理

JDK动态代理模式

API介绍

Proxy
  • 使用JDK的动态代理的要求:目标对象必须实现了接口。

  • 相关类:JDK的类java.lang.reflect.Proxy,提供了生成代理对象的方法

  • 生成代理对象的方法:
    Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces, InvocationHandler h)

    • loader:类加载器
    • interfaces:目标对象所实现的接口 字节码数组
    • h:用于写代理对象要做的事情,通常写成InvocationHandler接口的匿名内部类,实现其invoke方法
InvocationHandler接口
  • 接口只有一个方法:每次当代理对象被调用时,这个方法都会执行。在方法里通常写代理对象的行为
    invoke(Object proxy, Method method, Object[] args)
  • 方法的参数:
    • Object proxy:最终生成的代理对象
    • Method method:用户在调用代理对象时,所执行的方法对象
    • Object[] args:用户在调用代理对象,执行方法时,所传递的实参
  • 方法的返回值:
    • 当用户调用的代理对象的方法后,得到的返回值

使用示例

核心代码

 // 创建代理对象
         Proxy.newProxyInstance(
                targetObj.getClass().getClassLoader(), //目标对象使用什么类加载器,代理对象就使用什么类加载器
                targetObj.getClass().getInterfaces(), // 目标类实现什么接口,代理类也实现什么接口
                new InvocationHandler() { //调用处理器,用于协调代理对象和真实对象之间的对话

                    /**
                     * 外面的代理对象,执行什么方法,那么这个invoke方法都会被执行。
                     * @param proxy  代理对象
                     * @param method 外面用代理对象调用的方法对象
                     * @param args 调用方法用到的参数
                     * @return 真实对象的方法执行完毕的返回结果。
                     * @throws Throwable
                     */
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //System.out.println("调用了invoke~!~");
                        //增强功能的代码
                        //使用反射的手段让方法执行
                        Object obj = method.invoke(targetObj , args);
                        //增强功能的代码
                        return obj;
                    }
                }
        );

2.cglib的基于子类的动态代理

cglib

API介绍

Enhancer
  • 使用cglib的要求:

    • 目标对象不需要有接口
    • 目标类不能是final类
    • 要增强的方法不能是final方法
  • 相关类介绍:

    • jar包:Spring框架已经把cglib包含进去了,所以只要导入spring-context即可
    • 核心类:org.springframework.cglib.proxy.Enhancer,提供了生成代理对象的方法
  • 生成代理对象的方法:

    Enhancer.create(Class superClass, Callback callback)

    • superClass:目标对象的字节码

    • callback:回调函数,用于写代理对象要做的事情,通常写成MethodInterceptor的匿名内部类对象

      callback相当于jdk动态代理中的InvocationHandler

MethodInterceptor接口
  • 接口只有一个方法:每次当代理对象被调用时,这个方法都会执行。在方法里通常写代理对象的行为
    intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
  • 方法的参数:
    • Object proxy:最终生成的代理对象
    • Method method:用户在调用代理对象时,所执行的方法对象
    • Object[] args:用户在调用代理对象,执行方法时,所传递的实参
    • MethodProxy methodProxy:用户在调用代理对象时,所执行的方法的代理对象
      • methodProxy.invokeSuper(proxy, args):调用目标对象的方法,性能更强
  • 方法的返回值:
    • 当用户调用的代理对象的方法后,得到的返回值

使用示例

核心代码

Enhancer.create(
                Super.class,  // 父类是谁
                new MethodInterceptor() { // 方法拦截器,外面使用代理对象调用什么方法,下面的这个intercept都会执行
                    /**
                     * 外面使用代理对象执行方法,这个intercept都会执行
                     * @param o 代理对象
                     * @param method 方法对象
                     * @param objects 参数
                     * @param methodProxy 方法代理
                     * @return 把真实对象的方法执行结果返回出去
                     * @throws Throwable
                     */
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        //System.out.println("执行了intercept方法~!");
                        //在这里面让被代理对象的方法执行
                        //使用反射的手法来调用
                        Object result = method.invoke(targetObj, objects);
                        return result;
                    }
                }
        );
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值