模拟JDK动态代理实现

JDK动态代理

在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例。在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层技术。

JDK的动态代理主要涉及java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。而Proxy为InvocationHandler实现类动态创建一个复合某一接口的代理的实例。

JDK动态代理其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类完成对目标对象的代理。这点也是与CGLIB代理最大不同之处,CGLIB代理是针对类生成代理。

JDK动态代理的使用

要想模拟JDK动态代理的实现,首先要明白它的内在机理,知道它对外开放的接口方法。借用上篇文章中记录JDK动态代理时的简单示例,仅包括两个类:TimeHandler类和Test类,来回顾下JDK动态代理的使用。

package com.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 *  JDK动态代理步骤:
 *   1创建一个实现InvocationHandler的类,必须实现invoke方法
 *   2.创建被代理的类和接口
 *   3.调用Proxy的静态方法,创建一个代理类
 *   4.通过代理调用方法.
 *
 */
public class TimeHandler implements InvocationHandler {
   

    private Object object;

    public TimeHandler(Object object) {
        super();
        //代理对象
        this.object = object;
    }

    /**
     * proxy: 代理对象
     * method: 被代理对象的方法
     * args:方法的参数
     * return:  调用方法的返回值
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        long startTime = System.currentTimeMillis();
        System.out.println("汽车开始行驶");

        method.invoke(object);

        long endTime = System.currentTimeMillis();
        System.out.println("汽车行驶结束,行驶时间为:"+(endTime-startTime)+" ms");
        return null;
    }

}
package com.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

import com.proxy.Car;
import com.proxy.Moveable;

public class Test {
   

    public static void main(String[]args){
        Car car = new Car();
        InvocationHandler h = new TimeHandler(car);
        Class<?> cls = car.getClass();
        /**
         * loader:类加载器
         * interfaces:实现的接口
         * h InvocationHandler
         */
        Moveable  m = (Moveable) Proxy.newProxyInstance(
                cls.getClassLoader(), cls.getInterfaces(), h);
        m.move();
    }
}

运行结果:
这里写图片描述

JDK动态代理实现思路

如以上Test类中,通过Proxy的newProxyInstance()方法动态产生一个代理。模拟JDK动态代理实现流程,同样要自定义一个Proxy类并在类中实现产生动态代理的方法,这也是实现JDK动态代理的关键点和主要功能。

动态代理实现步骤如下

  1. 声明一段源码(动态产生代理)
  2. 编译源码(JDK Compiler API),产生代理类
  3. 将新产生的代理类load到内存当中,产生一个新的对象即代理对象
  4. 在newProxyInstance方法中返回这个代理对象

声明一段源码(动态产生代理)
将源码定义为字符串,Proxy类中代码如下:

package com.myJDKproxy;

public class Proxy {

    public static Object newProxyInstance(){
        String rt = "\r\t";
        String str = 
         "package com.myJDKproxy;" + rt +
         "public class $Proxy0 implements Moveable{"+ rt +
         "private Moveable m;"+ rt +
         "   public $Proxy0(Moveable m) {"+ rt +
         "      super();"+ rt +
         "      this.m = m;"+ rt +
         "   }"+ rt +
         "   @Override"+ rt +
         "   public void move() {"+ rt +
         "     long startTime = System.currentTimeMillis();"+ rt +
         "     System.out.println(\"汽车开始行驶\");"+ rt +
         "     m.move();"
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值