重要程度:★★★★☆ 一、什麼是代理模式 通過代理對象間接控制並訪問目標對象的方法; 二、補充說明 想到代理模式,容易讓人想到AOP思想,Spring中的AOP可以通過動態代理實現; 代理模式有靜態代理和動態代理兩種; 解耦調用者和被調用者; 三、角色 抽象主題,定義一些需要代理的方法 具體主題,實
重要程度:★★★★☆
一、什麼是代理模式
通過代理對象間接控制並訪問目標對象的方法;
二、補充說明
想到代理模式,容易讓人想到AOP思想,Spring中的AOP可以通過動態代理實現;
代理模式有靜態代理和動態代理兩種;
解耦調用者和被調用者;
三、角色
抽象主題,定義一些需要代理的方法
具體主題,實現一些具體邏輯
代理主題,代理和封裝具體主題
客戶端Main:調用者,通過代理主題訪問具體主題
四、例子,JAVA實現
這裡我們模擬代理上網場景:應用伺服器返回信息給代理伺服器,代理伺服器返回信息給客戶端;
抽象主題,伺服器介面,有一個response方法,能夠返回信息
1 package com.pichen.dp.structuralpattern.proxy; 2 public interface Server { 3 4 public String response(); 5 }
具體主題,某個具體的應用伺服器
1 package com.pichen.dp.structuralpattern.proxy; 2 public class ApplicationServer implements Server{ 3 4 @Override 5 public String response() { 6 //System.out.println("response from ApplicationServers。"); 7 return "response from ApplicationServers"; 8 } 9 10 }
靜態代理主題角色, 對具體主題的直接引用,直接調用具體主題里的方法
1 package com.pichen.dp.structuralpattern.proxy; 2 public class StaticProxyServer implements Server { 3 4 private ApplicationServer appServer; 5 @Override 6 public String response() { 7 //System.out.println("response from ProxyServer。"); 8 if(null == appServer){ 9 appServer = new ApplicationServer(); 10 } 11 //before , you can do something 12 String str = appServer.response() + "(by ProxyServer, static proxy.)"; 13 //after , you can do something 14 return str; 15 } 16 17 }
動態代理InvocationHandler,可以通過它獲取動態代理主題角色,代理對象是在運行期間動態生成的;
1 package com.pichen.dp.structuralpattern.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 public class DynamicProxyServerHandler implements InvocationHandler{ 8 9 private Server appServer; 10 11 public DynamicProxyServerHandler(Server appServer) { 12 this.appServer = appServer; 13 } 14 15 //獲取動態代理對象 16 public Object getProxyyServer(){ 17 return Proxy.newProxyInstance(appServer.getClass().getClassLoader(), 18 appServer.getClass().getInterfaces(), this); 19 } 20 21 @Override 22 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 23 //before , you can do something 24 Object str = method.invoke(appServer, args); 25 //after , you can do something 26 return str.toString() + "(by ProxyServer, dynamic proxy.)"; 27 } 28 29 }
客戶端,Main類,通過代理伺服器獲取應用伺服器的返回信息
1 package com.pichen.dp.structuralpattern.proxy; 2 3 public class Main { 4 public static void main(String[] args) { 5 //靜態代理 6 Server staticProxyServer = new StaticProxyServer(); 7 System.out.println(staticProxyServer.response()); 8 9 //動態代理 10 DynamicProxyServerHandler dpshandler = new DynamicProxyServerHandler(new ApplicationServer()); 11 Server dynamicProxyServer = (Server) dpshandler.getProxyyServer(); 12 System.out.println(dynamicProxyServer.response()); 13 } 14 }
結果列印
response from ApplicationServers(by ProxyServer, static proxy.) response from ApplicationServers(by ProxyServer, dynamic proxy.)