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 代理了。
代理模式的本質:控制對象訪問