1、本节主要点java
代理的概念 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 代理了。
代理模式的本质:控制对象访问