最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中靜態(tài)代理與動態(tài)代理的實現(xiàn)及區(qū)別對比分析

 更新時間:2025年12月09日 11:43:30   作者:沓然  
文章介紹了靜態(tài)代理和動態(tài)代理的區(qū)別,靜態(tài)代理通過在編譯時生成代理類來實現(xiàn)對真實對象的代理,而動態(tài)代理通過反射機制在運行時生成代理類,更加靈活,兩者都實現(xiàn)了對真實對象功能的擴展,但動態(tài)代理更為高效,適用于需要代理大量對象的情況,感興趣的朋友跟隨小編一起看看吧

Spring中靜態(tài)代理與動態(tài)代理的區(qū)別

前言

代理模式在Java中特別常見,如spring AOP功能就是用代理來實現(xiàn)的。代理模式作用是:在不修改被代理對象功能的基礎(chǔ)上,通過對代理類進行擴展,進行一些功能上的附加與增強。
一般使用代理模式我們需要先定義一個接口,靜態(tài)代理只是一種簡單的java代碼功能擴展。而動態(tài)代理利用了反射機制,使用更簡單。

無論是靜態(tài)代理還是動態(tài)代理,都有四大角色:

  1. 抽象角色:一般會使用接口或者抽象類來解決
  2. 真實角色:被代理的角色
  3. 代理角色:代理真實角色,代理真實角色后,我們一般會做一些附屬操作
  4. 客戶:訪問代理對象的人

靜態(tài)代理(中介租房案例)

首先,定義一個接口(Rent),房東類(Host)實現(xiàn)該接口,并輸出自己房子的相關(guān)信息。

//租房
public interface Rent {
    public  void rent();
}
//房東
public class Host implements Rent{
    public void rent() {
        System.out.println("我的房子是藍色的,準備出租房子!");
    }
}

房東將房子交給中介,此時的中介相當于代理類,故創(chuàng)建代理類(Proxy),代理類在不修改被代理對象功能的基礎(chǔ)上(Host類的rent方法),可以對代理類進行擴展,進行一些功能上的附加與增強(增加seeHouse、hetong、fare方法)。

public class Proxy implements Rent{
    private Host host;
    public Proxy(){ }
    public Proxy(Host host){
        this.host=host;
    }
    public void rent() {
        seeHouse();
        host.rent();
        hetong();
        fare();
    }
    //看房
    public void seeHouse(){
        System.out.println("中介帶你看房子");
    }
    //簽合同
    public void hetong(){
        System.out.println("簽合同");
    }
//    收費
    public void fare(){
        System.out.println("收中介費");
    }
}

客戶購房不用面對房東,只需與中介對接。

public class Client {
    public static void main(String[] args) {
        Host host=new Host(); //房東要出租房子
        //代理,中介幫房東租房子,但是代理角色一般會有一些附屬操作
        Proxy proxy=new Proxy(host);
        //客戶不用面對房東,直接找中介租房即可
        proxy.rent();
    }
}

上述代碼就實現(xiàn)了靜態(tài)代理,客戶只需面向代理類操作即可。

運行截圖:

靜態(tài)代理的優(yōu)點:

  1. 可以使真實角色的操作更加純粹,不用去關(guān)注一些公共的業(yè)務(wù)
  2. 公共也就交給代理角色,實現(xiàn)了業(yè)務(wù)的分工
  3. 業(yè)務(wù)發(fā)生擴展的時候,方便集中管理

靜態(tài)代理的缺點:

  1. 一個真實角色就會產(chǎn)生一個代理角色,代碼量會翻倍,開發(fā)效率變低。

動態(tài)代理

靜態(tài)代理中,每個真實對象都會擁有一個代理類,這樣將會十分繁瑣,采用動態(tài)代理將會解決這種問題!我們在上述的中介租房案例中進行修改。

首先創(chuàng)建一個Rent接口,并創(chuàng)建兩個房東類實現(xiàn)Rent接口。

//租房
public interface Rent {
    public  void rent();
}
//房東1
public class Host implements Rent {
    public void rent() {
        System.out.println("我的房子是藍色的,準備出租房子!");
    }
}
//別的房東
public class Host_other implements Rent{
    public void rent() {
        System.out.println("我的房子是紅色的,準備出租房子!");
    }
}

如果采用靜態(tài)代理,我們將要編寫兩個代理類,當房東數(shù)量很大時,這種處理方法明顯不妥,因此我們可以編寫一個代理工具類,該類并未指明代理的真實對象是哪一個,相當于我們之前學Java時編寫的Math類(完成某種特定的計算過程)。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//我們會用這個類自動生成代理類
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Object target;
    public void setTarget(Object target){
        this.target=target;
    }
    //生成得到代理類
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    //處理代理實例,并返回結(jié)果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //動態(tài)代理的本質(zhì),就是使用反射機制實現(xiàn)
        seeHouse();
        Object result=method.invoke(target,args);
        fare();
        return result;
    }
    public void seeHouse(){
        System.out.println("中介帶你看房子");
    }
    public void fare(){
        System.out.println("收中介費");
    }
}

其中的target變量,就是未來客戶類傳入的真實對象。很明顯,動態(tài)代理也能在不改變原有業(yè)務(wù)代碼的基礎(chǔ)上,實現(xiàn)對功能的擴展(seeHouse等方法的加入)。

在客戶類中,只需new多個代理工具類,并為他們傳入相應的真實對象,就可以獲取各個真實對象的rent方法。

public class Client {
    public static void main(String[] args) {
        //真實角色
        Host host=new Host();
        //代理角色:現(xiàn)在沒有
        ProxyInvocationHandler pih=new ProxyInvocationHandler();
        //通過調(diào)用程序處理角色來處理我們要調(diào)用的接口對象!
        pih.setTarget(host);
        Rent proxy=(Rent)pih.getProxy();//這里的proxy就是動態(tài)生成的,我們并沒有寫這個類
        proxy.rent();
        System.out.println("--------------------------");
        //真實角色
        Host_other host_other=new Host_other();
        //代理角色:現(xiàn)在沒有
        ProxyInvocationHandler pih1=new ProxyInvocationHandler();
        //通過調(diào)用程序處理角色來處理我們要調(diào)用的接口對象!
        pih1.setTarget(host_other);
        Rent proxy1=(Rent)pih1.getProxy();//這里的proxy1就是動態(tài)生成的,我們并沒有寫這個類
        proxy1.rent();
    }
}

運行結(jié)果見下圖:

動態(tài)代理的好處:

  1. 可以使真實角色的操作更加純粹,不用去關(guān)注一些公共的業(yè)務(wù)
  2. 公共業(yè)務(wù)就交給代理角色,實現(xiàn)了業(yè)務(wù)分工
  3. 公共業(yè)務(wù)發(fā)生擴展的時候,方便集中管理
  4. 一個動態(tài)代理類代理的是一個接口,一般就是對應的一類業(yè)務(wù)(多個類實現(xiàn)同一個接口,只要重寫方法,客戶端可以通過修改代理的真實對象來實現(xiàn)動態(tài)的代理)
  5. 多個房東同時賣房,他們的房子信息不一樣,如果采用靜態(tài)代理,需要為他們各自寫一個代理類,就十分麻煩。我們可以采用動態(tài)代理的方法,讓這些房東同時實現(xiàn)一個接口(Rent),這樣我們在客戶類只需要修改代理的真實對象,就可以得到每個房東各自的房子信息。

總結(jié)

無論是靜態(tài)代理還是動態(tài)代理,都符合下面幾個步驟:

  1. 創(chuàng)建接口
  2. 創(chuàng)建真實角色并實現(xiàn)接口
  3. 創(chuàng)建代理類
  4. 客戶類訪問代理角色

不同的是靜態(tài)代理需要為每個真實對象創(chuàng)建一個代理類,而動態(tài)代理只用為同一類業(yè)務(wù)創(chuàng)建一個代理工具類即可。

到此這篇關(guān)于Spring中靜態(tài)代理與動態(tài)代理的實現(xiàn)及區(qū)別的文章就介紹到這了,更多相關(guān)Spring靜態(tài)代理與動態(tài)代理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

深州市| 苍溪县| 北流市| 红桥区| 辽阳市| 车致| 遵义市| 红安县| 赤城县| 澜沧| 盈江县| 阜新市| 株洲市| 观塘区| 宝丰县| 新余市| 金门县| 武隆县| 五家渠市| 金山区| 云安县| 新蔡县| 宁波市| 宁德市| 濮阳市| 恩施市| 伊金霍洛旗| 九龙坡区| 东城区| 天气| 龙口市| 岗巴县| 昭通市| 商丘市| 蒲城县| 阿克陶县| 崇州市| 江源县| 类乌齐县| 神农架林区| 长春市|