动态代理讲解(一)之反射≈复用?

1、介绍

  在讲解动态代理之前,我们要弄懂一个概念:
  什么是代理模式?

可以看成是对调用目标的一个封装,我们对目标代码的调用不是解法发生的,而是通过代理完成的,这在一定程度上解决了调用者和实现者这之间的耦合。

 什么意思呢?
 举个例子吧,比如说我们要租房,最省事的办法就是找个中介,你只要告诉他你需要什么型号的房,然后啥都不用管,他会帮你找房,非常省事,他会帮你找合适的房东,你最后只要交钱就行了,那么在这里,房东就是调用目标,而中介就是我们所说的代理者,你可以根据代理者而间接达到你租房的目的。那么这个场景用代码怎么实现呢?

public interface Room {
    void rent();
}
class RoomImpl implements Room{
    @Override
    public void rent() {
        System.out.println("三室一厅");
    }
}
class RoomProxy implements Room{
    private Room room;
    public RoomProxy(Room room){
        this.room = room;
    }
    @Override
    public void rent() {
        System.out.println("租房前准备");
        room.rent();
        System.out.println("租完了");
    }
}
public class Client {
    public static void main(String[] args) {
        RoomImpl impl = new RoomImpl();
        RoomProxy proxy = new RoomProxy(impl);
        proxy.rent();
    }
}
image.png

这样你就应该有个比较直观的感觉了吧?那么你想一下这样写有没有什么不足?想一想,如果我一个类中所代理的方法有很多,这样是不是要无形之中增加很多方法?还有,像刚刚这个例子,每次租房前都要准备合同啊等各种必要工作,那是不是会产生代码冗余呢?而且维护起来也不方便,那么有什么办法能解决这样一个问题呢?

哎!这时候动态代理就出来了,利用反射机制,可以使得相应的调用操作动态完成。看运行时调用哪个就代理哪个,这样就只需要一个方法就可以了,这样是不是就实现了复用了呢?

提供一下代码瞧瞧吧!这样比较直观:

public class DynaProxy {

    public static void main(String[] args) {
        Work work = new WorkImpl();
        MyInvocationHandle handle = new MyInvocationHandle(work);

        Work proxy = (Work) Proxy.newProxyInstance(WorkImpl.class.getClassLoader(),WorkImpl.class.getInterfaces(),
                                             handle);
        proxy.dowork();
    }
}

interface Work{
    void dowork();
}

class WorkImpl implements Work{

    @Override
    public void dowork() {
        System.out.println("do work");
    }
} 
class MyInvocationHandle implements InvocationHandler{

    private Object object;//被代理对象

    public MyInvocationHandle(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("befor");
        Object result = method.invoke(object,args);
        System.out.println("after");
        return result;
    }
}

首先我们实现InvocationHandler,以接口为纽带构建Proxy代理对象,通过对代理对象的调用间接实现对目标对象的调用

newProxyInstance返回的是一个实现了dowork接口的一个代理类。

你可能感兴趣的:(动态代理讲解(一)之反射≈复用?)