Spring中常用的設計模式之:代理模式

 

看了tom老師講的深入分析spring源碼,講的挺好,做個小總結

代理模式的定義:

爲其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用。

比如:

租房中介、火車票黃牛、媒人、經紀人、快遞   

這些人和你之間的關係可以算作爲代理模式,在我需要租房、買票、拿快遞時我可以找一個這個中間人去替我辦這件事

代理模式需要滿足的特點:

1、執行者、被代理人

2、對於被代理人來說,這件事情是一定要做的,但是我自己又不想做或者沒有時間做,找代理。

3、需要獲取到被代理的人個人資料。

 

代理模式和裝飾模式區別:

代理模式關心的不是結果 是過程;裝飾模式關心的是最終結果

下面是一個小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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章