代理模式定義:爲其餘對象提供了一種代理以控制對這個對象的訪問。java
代理模式的三種角色:設計模式
Subject抽象主題角色:抽象主題類能夠是抽象類也能夠是接口,是一個最普通的業務類型定義,無特殊要求。ide
RealSubject具體主題角色:也叫作被委託角色、被代理角色。它纔是冤大頭,是業務邏輯的具體執行者,Subject接口的實現。學習
Proxy代理主題角色:也叫作委託類、代理類。它負責對真實角色的應用,把全部抽象主題類定義的方法限制委託給真實主題角色實現,而且在真實主題角色處理完畢前作預處理和藹後工做。this
一句話描述靜態代理和動態代理:spa
靜態代理:一個主題類與一個代理類一一對應。.net
動態代理:多個主題類對應一個代理類。設計
靜態代理的例子:3d
Subject接口:代理
package com.design.one; public interface Subject { void doSomething(); }
RealSubject類:
package com.design.one; public class RealSubject implements Subject{ @Override public void doSomething() { System.out.println("doSomething()......"); } }
Proxy類:
package com.design.one; public class Proxy implements Subject{ Subject subject = null; public Proxy(Subject subject) { this.subject = subject; } @Override public void doSomething() { System.out.println("以前"); subject.doSomething(); System.out.println("以後"); } }
Client類:
package com.design.one; public class Client { public static void main(String[] args) { Subject sub = new RealSubject(); Proxy proxy = new Proxy(sub); proxy.doSomething(); } }
輸出結果:
以前
doSomething()......
以後
動態代理的例子:
引子:通常來講,使用靜態代理,都須要每個RealSubject編寫一一對應的代理類,這些類在編譯期間就已經肯定了的,若是有多個RealSubject類,可是他們的代理類裏面的前處理(「以前」)和後處理(「以後」)是同樣的,那麼使用靜態代理模式爲多個RealSubject類編寫相同的處理邏輯的代理類就顯得臃腫了和多餘了。而動態代理不一樣,它能使多個RealSubject類對應一個代理類,共享「前處理,後處理」功能,動態調用所需主題,大大減少了程序規模。
Subject類:
package com.design.three; public interface Subject { void doSomething(); void doSomething1(); }
Subject2類:
package com.design.three; public interface Subject2 { void doSomething3(); void doSomething4(); }
RealSubject類:
package com.design.three; public class RealSubject implements Subject,Subject2{ @Override public void doSomething() { System.out.println("doSomething()......"); } @Override public void doSomething1() { System.out.println("doSomething()1......"); } @Override public void doSomething3() { System.out.println("doSomething()3......"); } @Override public void doSomething4() { System.out.println("doSomething()4......"); } }
RealSubject2類:
package com.design.three; public class RealSubject2 implements Subject,Subject2{ @Override public void doSomething() { System.out.println("Subject2doSomething()......"); } @Override public void doSomething1() { System.out.println("Subject2doSomething()1......"); } @Override public void doSomething3() { System.out.println("Subject2doSomething()3......"); } @Override public void doSomething4() { System.out.println("Subject2doSomething()4......"); } }
MyInvocationHandler類:
package com.design.three; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler{ private Object obj = null; public MyInvocationHandler(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法前...."); return method.invoke(obj, args); } }
Client類:
package com.design.three; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { Subject sub = new RealSubject();//1 // Subject sub = new RealSubject2();//2 InvocationHandler handler = new MyInvocationHandler(sub); Subject proxy = (Subject) Proxy.newProxyInstance(sub.getClass() .getClassLoader(), sub.getClass().getInterfaces(), handler); proxy.doSomething(); } }
輸出結果:
方法前....
doSomething()......
把2註釋打開,1註釋掉,輸出結果:
方法前....
Subject2doSomething()......
接下來是四篇我的認爲比較好的學習動態代理的文章,具體原理和分析都在下面了,我就再也不累贅了: