如何理解代理?

1、本节主要点java

  1. 代理的概念
  2. 静态代理和动态代理

 

代理的概念 ide

什么是代理呢?this

代理,就是一个角色表明另外一个角色去完成某件事。spa

好比,你肚子饿了,又懒得出去吃饭,这时候,你的朋友正好要出去,你让他帮忙打包。那他就是代理类。你就是委托他去作事。代理

这个代理类在帮你打包的同时,他还能够本身打包,或者顺便去买包烟。code

那这个代理类有什么做用呢? 对象

就是完成目标类 以前能够作点其余什么的。以后能够作点什么。blog

静态代理接口

在运行以前,代理的类已经肯定。get

例子以下:

一、Pack 接口

public interface Pack {
    public void giveMePack();
}

二、PackImpl 类

public class PackImpl implements Pack {
    @Override
    public void giveMePack() {
        System.out.println("帮我打包吧,中午下雨啊");
    }
}

3 proxy 代理类

/**代理类
 * Created by hp on 14-7-27.
 */
public class Proxy implements Pack {

    public PackImpl pack;

    public Proxy(PackImpl pack) {
        this.pack = pack;
    }

    @Override
    public void giveMePack() {
        System.out.println("哥去买包烟先,再帮你打包");
        pack.giveMePack();
        System.out.println("垃圾太多了,倒掉吧");
    }
}

四、ClientText 类

public class ClientText {
    public static void main(String[] args) {
        PackImpl pack = new PackImpl();
        Proxy proxy = new Proxy(pack);
        proxy.giveMePack();

    }
}

以上就是静态代理的实现代码。它有一个特色:

一个代理类只服务于一个接口。

这样若是有许多这样的代理,那就有不少的代理类出现。因此,最好是有一个代理类能够完成所有的代理功能。这就是下面要讲的动态代理了。

动态代理

解释一下,动态代理就是在程序运行中由Java的反射机制动态生成。

先看一下JDK对动态代理的支持,java.lang.reflect 包中的 InvocationHandler 接口和 Proxy 类。

一、InvocationHandler 接口

public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;

Object proxy:被代理的对象。 
     Method method:要调用的方法 
     Object[] args:方法调用须要的参数

二、Proxy类

这个是完成代理的操做类。其中有一个方法是这样的

ClassLoader loader:类加载器 
     Class<?>[] interfaces:获得所有的接口 
     InvocationHandler h:获得InvocationHandler接口的子类实例

public static Object newProxyInstance(ClassLoader loader,
                      Class<?>[] interfaces,
                      InvocationHandler h)
    throws IllegalArgumentException
    {
    if (h == null) {
        throw new NullPointerException();
    }

    /*
     * Look up or generate the designated proxy class.
     */
    Class cl = getProxyClass(loader, interfaces);

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        Constructor cons = cl.getConstructor(constructorParams);
        return (Object) cons.newInstance(new Object[] { h });
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString());
    } catch (IllegalAccessException e) {
        throw new InternalError(e.toString());
    } catch (InstantiationException e) {
        throw new InternalError(e.toString());
    } catch (InvocationTargetException e) {
        throw new InternalError(e.toString());
    }
    }

 

代理类实例:

/**
 * JDK 的动态代理
 * Created by hp on 14-7-27.
 */
public class DynamicProxy implements InvocationHandler {

    private Object object;

    public Object getProxyInterface(Object object) {
        this.object = object;
        // 获取代理对象
        Object o = Proxy.newProxyInstance(object.getClass().getClassLoader(),
                object.getClass().getInterfaces(), this);
        return o;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("哥去买包烟先,再帮你打包");
        Object result = method.invoke(object, args);
        System.out.println("垃圾太多了,倒掉吧");
        return result;
    }
}

从JDK动态代理能够看出。代理类的变化:

一、实现了InvocationHandler接口。

二、把目标对象和动态代理绑定起来。便于客户端调用。

三、实现invoke 方法。

JDK动态代理,只能代理实现接口的类。若是针对类来实现代理,则须要cglib 代理了。


代理模式的本质:控制对象访问

相关文章
相关标签/搜索