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

什麼是代理模式

舉個例子,我是一個包租公,我如今想賣房,可是我不想麻煩,天天被電話騷擾,因此這個時候我找了樓下一個中介,讓他幫我代理這些事,那麼他天然有租房的方法。之後若是有人想租房,直接找中介就好了。html

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())不就好了,那麼爲何屢次一舉呢,任何設計都有他的好處。咱們能夠發現代理類能夠在真實類的基礎上增長方法,好比這個時候中介能夠收取買主的費用。java

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要買房");
    }
}

這個時候我要生成兩個代理,那麼我就要建立兩個代理類ide

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();

    }
}

若是我要爲多種方法代理,那麼就會產生不少代理類。this

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

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代理設計

我以爲分享是一種精神,分享是個人樂趣所在,不是說我以爲我講得必定是對的,我講得可能不少是不對的,可是我但願我講的東西是我人生的體驗和思考,是給不少人反思,也許給你一秒鐘、半秒鐘,哪怕說一句話有點道理,引起本身心裏的感觸,這就是我最大的價值。(這是我喜歡的一句話,也是我寫博客的初衷)

相關文章
相關標籤/搜索