Android中的代理模式

代理的概念:爲某個對象提供一個代理,以控制對這個對象的訪問。 代理類和委託類有共同的父類或父接口,這樣在任何使用委託類對象的地方均可以用代理對象替代。代理類負責請求的預處理、過濾、將請求分派給委託類處理、以及委託類執行完請求後的後續處理。 

 

 抽象對象角色:就是代理類和委託類共同的接口,聲明瞭目標對象和代理對象的共同接口,這樣一來在任何能夠使用目標對象的地方均可以使用代理對象。 目標對象角色:就是委託類,定義了代理對象所表明的目標對象。 代理對象角色:就是代理類,代理對象內部含有目標對象的引用,從而能夠在任什麼時候候操做目標對象;代理對象提供一個與目標對象相同的接口,以即可以在任什麼時候候替代目標對象。代理對象一般在客戶端調用傳遞給目標對象以前或以後,執行某個操做,而不是單純地將調用傳遞給目標對象。 靜態代理 代理類在程序運行前已經存在的代理方式稱爲靜態代理。 /** * 定義Demo接口 */
    public interface Demo { public void save(); } /** * DemoImpl實現Demo接口並覆寫save()方法 * 真實主題,執行具體業務 */
    public class DemoImpl implements Demo { public void save() { System.out.println("調用save()方法"); } } /** * DemoImplProxy 也實現了Demo接口,並覆寫了save()方法,增長了本身的業務 * 代理主題,負責其餘業務的處理 */
    public class DemoImplProxy implements Demo { Demo demoImpl = new DemoImpl(); public void save() { System.out.println("開始記錄日誌"); demoImpl.save(); System.out.println("開始結束日誌"); } } 靜態代理有一個缺點,每一個代理類只能爲一個接口服務,這樣程序開發中必然會產生許多的代理類。 動態代理 代理類在程序運行前不存在、運行時由程序動態生成的代理方式稱爲動態代理。 實現動態代理包括三步: (1). 新建代理類和委託類共同的接口以及委託類; (2). 實現InvocationHandler接口,這是負責鏈接代理類和委託類的中間類必須實現的接口; (3). 經過Proxy類新建代理類對象。 第一步:新建代理類和委託類共同的接口以及委託類 public interface Operate { public void operateMethod1(); public void operateMethod2(); public void operateMethod3(); } public class OperateImpl implements Operate { @Override public void operateMethod1() { System.out.println("Invoke operateMethod1"); sleep(110); } @Override public void operateMethod2() { System.out.println("Invoke operateMethod2"); sleep(120); } @Override public void operateMethod3() { System.out.println("Invoke operateMethod3"); sleep(130); } private static void sleep(long millSeconds) { try { Thread.sleep(millSeconds); } catch (InterruptedException e) { e.printStackTrace(); } } } 第二步:實現InvocationHandler接口 java.lang.reflect.InvocationHandler接口的定義以下: /** * *Object proxy:被代理的對象 *Method method:要調用的方法 *Object[] args:方法調用時所須要參數 */
    public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; } 實現 InvocationHandler 接口 public class TimingInvocationHandler implements InvocationHandler { private Object target; public TimingInvocationHandler() {} public TimingInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long start = System.currentTimeMillis(); Object obj = method.invoke(target, args); System.out.println(method.getName() + " cost time is:" + (System.currentTimeMillis() - start)); return obj; } } 第三步:經過Proxy類新建代理類對象 java.lang.reflect.Proxy類的定義以下: /** *CLassLoader loader:類的加載器 *Class<?> interfaces:獲得所有的接口 *InvocationHandler h:獲得InvocationHandler接口的子類的實例 */
    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException public class Main { public static void main(String[] args) { // create proxy instance
            TimingInvocationHandler timingInvocationHandler = new TimingInvocationHandler(new OperateImpl()); Operate operate = (Operate)(Proxy.newProxyInstance(Operate.class.getClassLoader(), new Class[] {Operate.class}, timingInvocationHandler)); // call method of proxy instance
 operate.operateMethod1(); System.out.println(); operate.operateMethod2(); System.out.println(); operate.operateMethod3(); } } 下面總結一下動態代理對象建立過程 // InvocationHandlerImpl 實現了 InvocationHandler 接口,並能實現方法調用從代理類到委託類的分派轉發 // 其內部一般包含指向委託類實例的引用,用於真正執行分派轉發過來的方法調用
    InvocationHandler handler = new InvocationHandlerImpl(..); // 經過 Proxy 爲包括 Interface 接口在內的一組接口動態建立代理類的類對象
    Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... }); // 經過反射從生成的類對象得到構造函數對象
    Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class }); // 經過構造函數對象建立動態代理類實例
    Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler }); 從上面能夠看到,實際使用過程更加簡單,由於 Proxy 的靜態方法 newProxyInstance 已經爲咱們封裝了步驟 2 到步驟 4 的過程,因此簡化後的過程以下 // InvocationHandlerImpl 實現了 InvocationHandler 接口,並能實現方法調用從代理類到委託類的分派轉發
    InvocationHandler handler = new InvocationHandlerImpl(..); // 經過 Proxy 直接建立動態代理類實例
    Interface proxy = (Interface)Proxy.newProxyInstance( classLoader, new Class[] { Interface.class }, handler ); 參考文章: Java 動態代理機制分析 公共技術點之 Java 動態代理 代理模式和android插件化 Android設計模式源碼解析之Proxy模式
相關文章
相關標籤/搜索