深入理解jdk动态代理的实现过程

无意间想到java动态代理,百度一搜,简直多得吓人,但是自己没有看到一篇写的通俗易懂的,也有很多简析了深层原理的,所以自己也写一篇,写得不好,望见谅:

学习代理,先从概念入手:为其他对象提供一种代理来控制对这个对象的访问,所以代理起到的是中介的作用,可以去掉功能服务,也可以增加额外额功能服务

代理的分类有很多:比如远程代理,虚拟代理,保护代理,智能引用代理

从实现方式共分为两大类:动态代理和静态代理;

静态代理:有一个很有意思的叫法,装饰模式,即向原有的对象包装一下,现实中这样的例子很多,比如房子的装修,同样的一座大楼,每一层的架构都一样,但是不同的住户,

喜欢不同的风格,所以就装修成不一样,实现方式就继承模式和聚合模式,这两种方式的实现方式太简单,园子这样的文章太多了

动态代理:目前我知道的实现方式就基于JDK的,cglib的实现方式

本文就基于JDK动态代理实现方式做简单介绍:

1.创建一个事务处理器,TimeAndLogProxy并实现InvocationHandler

package com.mitko.proxy;

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

/**
 * 动态代理的实现方式
 * 该类实现时间和日志功能的打印
 * 代理类必须实现InvocationHandler中invoke方法,业务逻辑都在此方法中实现
 * @author Administrator
 *
 */
public class TimeAndLogProxy implements InvocationHandler {
    
    //代理对象
    private Object target;

    public TimeAndLogProxy(Object target) {
        this.target = target;
    }
    
    /**
     * proxy 代理对象
     * method 代理对象的方法
     * args 方法参数
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        
        Long beginTime = System.currentTimeMillis();
        System.out.println("日志记录开始:");
        Thread.sleep(10);
        method.invoke(target);
        Long endTime = System.currentTimeMillis();
        System.out.println("运行时间:"+(endTime-beginTime)+"ms "+"日志记录结束....");
        return null;
    }

}

2.创建一个接口

**
 * 所有实体类的共有的方法
 * @author Administrator
 *
 */
public interface MoveAble {
    
    public abstract void move();

}

3.创建被代理类并实现上面创建的接口

package com.mitko.model;

import com.mitko.MoveAble;
/**
 * 独立类
 * @author Administrator
 *
 */
public class Car implements MoveAble {

    @Override
    public void move() {
        
        System.out.println("汽车行驶在路上。。。。");

    }

}

至此,JDK动态代理实现就完成了,下面是测试

/**
 * 测试类
 * @author Administrator
 *
 */
public class ProxyTest {
    
    @Test
    public void test(){
        //代理的真实类,两种写法都可以
        Car car = new Car();
        MoveAble real = new Car();
        //创建事务处理器并传入需要代理的类
        TimeAndLogProxy talp = new TimeAndLogProxy(real);
        
        //通过Proxy创建被代理对象
        //loader 事务处理器的类加载器
        //interface 被代理对象所实现的接口
        //invocationHandler 事务处理器
        MoveAble m = (MoveAble)Proxy.newProxyInstance(
                                        talp.getClass().getClassLoader(), 
                                        real.getClass().getInterfaces(), 
                                        talp);
        m.move();
    }
}

 测试结果

以上就是jdk动态代理的实现过程,但是有一个局限性,jdk动态代理只能代理有实现接口的类,不能代理没有实现接口的类,这点与cglib有区别

欢迎大家在下面留言评论指正

posted @ 2018-04-04 14:28  诗波烟雨  阅读(159)  评论(0编辑  收藏  举报