學習spring前,先了解了解代理模式


什么是代理模式

舉個例子,我是一個包租公,我現在想賣房,但是我不想麻煩,每天被電話騷擾,所以這個時候我找了樓下一個中介,讓他幫我代理這些事,那么他自然有租房的方法。以后如果有人想租房,直接找中介就行了。

public interface Sale {
	public void sale();
}
public class Jiajun implements Sale{
    public void sale() {
		// TODO 自動生成的方法存根
		System.out.println("jiajun要賣房");
	}
}
public class SaleProxy implements Sale{

	Jiajun jiajun=new Jiajun();
	@Override
	public void sale() {
		// TODO 自動生成的方法存根
		jiajun.sale();
	}
	
}
public Client{
    public static void main(String[] args)
    {
        Sale saleProxy=new SaleProxy();
		saleProxy.sale();
    }
}

為什么用代理模式

從上面的代碼可以看出,代理類(SaleProxy)和真實類(Jiajun)好像沒什么區別,我直接(new Jiajun().sale())不就行了,那么為什么多次一舉呢,任何設計都有他的好處。我們可以發現代理類可以在真實類的基礎上增加方法,比如這個時候中介可以收取買主的費用。

public class SaleProxy implements Sale{

	Jiajun jiajun=new Jiajun();
	@Override
	public void sale() {
		// TODO 自動生成的方法存根
		charge();
		jiajun.sale();
	}
	public void charge()
	{
	    System.out.println("jiajun要賣房,中介要收費");
	}
	
}

而這個不關我事,中介你幫我租出去就行。

什么是動態代理模式

靜態代理模式有他的缺點:

  • 如果這個時候,我要做的事情增多了,比如我在賣房的時候,我還可以租房。那么我在Sale接口要增加一個方法,真實類(Jiajun)要實現多一個方法,此時代理類(SaleProxy)又要實現多一個方法,如果以后要拓展,會增加很多方法,那么就增加維護難度。
public interface Sale {
	public void sale();
	public void rent();
}
public class SaleProxy implements Sale{

	Jiajun jiajun=new Jiajun();
	@Override
	public void sale() {
		// TODO 自動生成的方法存根
		jiajun.sale();
	}
	public void rent()
	{
		jiajun.rent();
	}
}
  • 如果真實類(Jiajun)實現了多個接口,我要為多種方法代理,那么我要手動創建很多代理類。
    比如這里我實現了兩個接口。
public interface Sale {
	public void sale();
}

public interface Buy {
	public void buy();
}
public class Jiajun implements Sale,Buy{

	public void sale() {
		// TODO 自動生成的方法存根
		System.out.println("jiajun要賣房");
	}
	public void buy() {
		// TODO 自動生成的方法存根
		System.out.println("jiajun要買房");
	}
}

這個時候我要生成兩個代理,那么我就要創建兩個代理類

public class BuyProxy implements Buy{

	Jiajun jiajun=new Jiajun();
	public void buy() {
		// TODO 自動生成的方法存根
		jiajun.buy();
	}

}
public class SaleProxy implements Sale{

	Jiajun jiajun=new Jiajun();
	@Override
	public void sale() {
		// TODO 自動生成的方法存根
		jiajun.sale();
	}
	
}
public class Client {
	public static void main(String[] args) {
		
		Sale saleProxy=new SaleProxy();
		saleProxy.sale();
		Buy buyProxy=new BuyProxy();
		buyProxy.buy();

	}
}

如果我要為多種方法代理,那么就會產生很多代理類。

針對這些缺點,動態代理出現了

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyHandler implements InvocationHandler{


		private Object tar;

	    //綁定委托對象,並返回代理類
		public Object bind(Object tar)
		{
			this.tar=tar;
			//綁定該類實現的所有接口,取得代理類
			return Proxy.newProxyInstance(tar.getClass().getClassLoader(), tar.getClass().getInterfaces(), this);
		}

	    public Object invoke(Object proxy , Method method , Object[] args)throws Throwable
	    {
	        Object result = null;
	        result = method.invoke(tar,args);
	        return result;
	    }

}
public class Client {
	public static void main(String[] args) {

		
       ProxyHandler proxy = new ProxyHandler();
       //綁定該類實現的所有接口
       Sale saleProxy = (Sale) proxy.bind(new Jiajun());
       saleProxy.sale();;
       
       Buy buyProxy=(Buy)proxy.bind(new Jiajun());
       buyProxy.buy();

	}
}

顯然,上面的缺點得到解決了。

  • 即使接口增加方法,我也不用在代理類再實現一次。
  • 即使我要對不同方法做代理,我也不用創建一個代理類文件。
  • 動態代理類由Java反射機制動態生成,不用我們自己生成(這里我們並沒有看到買房代理類,賣房代理類文件)
  • 動態代理類不僅簡化了編程工作,而且提高了軟件系統的可擴展性,因為Java 反射機制可以生成任意類型的動態代理類。(我們要買房代理就買房代理,賣房代理就賣房代理,比較靈活)。
  • 總的來說,關鍵的就是我們避免了代理類文件的編寫,從而提高了許多便利。
  • 動態代理的實現:jdk代理和cglib代理

我覺得分享是一種精神,分享是我的樂趣所在,不是說我覺得我講得一定是對的,我講得可能很多是不對的,但是我希望我講的東西是我人生的體驗和思考,是給很多人反思,也許給你一秒鍾、半秒鍾,哪怕說一句話有點道理,引發自己內心的感觸,這就是我最大的價值。(這是我喜歡的一句話,也是我寫博客的初衷)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM