看了tom老師講的深刻分析spring源碼,講的挺好,作個小總結java
代理模式的定義:spring
爲其餘對象提供一種代理以控制對這個對象的訪問。在某些狀況下,一個對象不適合或者不能直接引用另外一個對象,而代理對象能夠在客戶端和目標對象之間起到中介的做用。ide
好比:測試
租房中介、火車票黃牛、媒人、經紀人、快遞 this
這些人和你之間的關係能夠算做爲代理模式,在我須要租房、買票、拿快遞時我能夠找一個這個中間人去替我辦這件事代理
代理模式須要知足的特色:code
一、執行者、被代理人對象
二、對於被代理人來講,這件事情是必定要作的,可是我本身又不想作或者沒有時間作,找代理。blog
三、須要獲取到被代理的人我的資料。接口
代理模式和裝飾模式區別:
代理模式關心的不是結果 是過程;裝飾模式關心的是最終結果
下面是一個小demo,建立了一個媒婆代理幫你找對象功能:
文件結構
Person類:
package spring; public interface Person { void findLove(); }
Zhansan類:
package spring; public class Zhansan implements Person{ private String sex = "女"; private String name = "Zhansan"; @Override public void findLove() { System.out.println("我叫:"+this.name+" 性別:"+this.sex); System.out.println("我要找高富帥"); } }
Meipo類:
package spring; import java.lang.annotation.Target; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Meipo implements InvocationHandler{ private Person target; //獲取被代理人的我的資料 public Object getInstance(Person target) { this.target = target; Class clazz = target.getClass(); //生成代理對象:3個參數:ClassLoader類加載器 實現接口,代理人 System.out.println("被代理對象是:"+clazz); return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我是媒婆,準備介紹"); System.out.println("------------"); this.target.findLove(); System.out.println("------------"); return null; } }
測試類:
package spring; public class TestFindLove { public static void main(String[] args) { Person obj = (Person) new Meipo().getInstance(new Zhansan()); System.out.println(obj.getClass()); obj.findLove(); /*原理: * 1 拿到帶代理對象的引用,而後獲取它的接口 * 2 jdk代理從新生成一個類,同時實現咱們給的代理對象所實現的接口 * 3 把被代理對象的引用也拿到了 * 4 從新動態生成一個class字節碼 * 5 編譯 */ } }
輸出結果:
能夠看到,測試類中雖然new的是一個zhangsan類 可是obj.getClass()的輸出是代理類com.sun.proxy.$Proxy0