代理模式定義:為其他對象提供了一種代理以控制對這個對象的訪問。 代理模式的三種角色: Subject抽象主題角色:抽象主題類可以是抽象類也可以是介面,是一個最普通的業務類型定義,無特殊要求。 RealSubject具體主題角色:也叫做被委托角色、被代理角色。它才是冤大頭,是業務邏輯的具體執行者,Su ...
代理模式定義:為其他對象提供了一種代理以控制對這個對象的訪問。
代理模式的三種角色:
Subject抽象主題角色:抽象主題類可以是抽象類也可以是介面,是一個最普通的業務類型定義,無特殊要求。
RealSubject具體主題角色:也叫做被委托角色、被代理角色。它才是冤大頭,是業務邏輯的具體執行者,Subject介面的實現。
Proxy代理主題角色:也叫做委托類、代理類。它負責對真實角色的應用,把所有抽象主題類定義的方法限制委托給真實主題角色實現,並且在真實主題角色處理完畢前做預處理和善後工作。
一句話描述靜態代理和動態代理:
靜態代理:一個主題類與一個代理類一一對應。
動態代理:多個主題類對應一個代理類。
靜態代理的例子:
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()......
接下來是四篇個人認為比較好的學習動態代理的文章,具體原理和分析都在下麵了,我就不再累贅了: