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

Spring中靜態(tài)代理與動(dòng)態(tài)代理的實(shí)現(xiàn)及區(qū)別對(duì)比分析

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

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

前言

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

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

  1. 抽象角色:一般會(huì)使用接口或者抽象類(lèi)來(lái)解決
  2. 真實(shí)角色:被代理的角色
  3. 代理角色:代理真實(shí)角色,代理真實(shí)角色后,我們一般會(huì)做一些附屬操作
  4. 客戶:訪問(wèn)代理對(duì)象的人

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

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

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

房東將房子交給中介,此時(shí)的中介相當(dāng)于代理類(lèi),故創(chuàng)建代理類(lèi)(Proxy),代理類(lèi)在不修改被代理對(duì)象功能的基礎(chǔ)上(Host類(lèi)的rent方法),可以對(duì)代理類(lèi)進(jìn)行擴(kuò)展,進(jìn)行一些功能上的附加與增強(qiáng)(增加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("簽合同");
    }
//    收費(fèi)
    public void fare(){
        System.out.println("收中介費(fèi)");
    }
}

客戶購(gòu)房不用面對(duì)房東,只需與中介對(duì)接。

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

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

運(yùn)行截圖:

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

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

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

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

動(dòng)態(tài)代理

靜態(tài)代理中,每個(gè)真實(shí)對(duì)象都會(huì)擁有一個(gè)代理類(lèi),這樣將會(huì)十分繁瑣,采用動(dòng)態(tài)代理將會(huì)解決這種問(wèn)題!我們?cè)谏鲜龅闹薪樽夥堪咐羞M(jìn)行修改。

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

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

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

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

其中的target變量,就是未來(lái)客戶類(lèi)傳入的真實(shí)對(duì)象。很明顯,動(dòng)態(tài)代理也能在不改變?cè)袠I(yè)務(wù)代碼的基礎(chǔ)上,實(shí)現(xiàn)對(duì)功能的擴(kuò)展(seeHouse等方法的加入)。

在客戶類(lèi)中,只需new多個(gè)代理工具類(lèi),并為他們傳入相應(yīng)的真實(shí)對(duì)象,就可以獲取各個(gè)真實(shí)對(duì)象的rent方法。

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

運(yùn)行結(jié)果見(jiàn)下圖:

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

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

總結(jié)

無(wú)論是靜態(tài)代理還是動(dòng)態(tài)代理,都符合下面幾個(gè)步驟:

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

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

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

相關(guān)文章

最新評(píng)論

米林县| 普定县| 两当县| 日土县| 长沙县| 从江县| 西畴县| 龙岩市| 贵德县| 淄博市| 冀州市| 荔波县| 鞍山市| 盐边县| 石城县| 满城县| 汕尾市| 和静县| 平原县| 元谋县| 中超| 彝良县| 太谷县| 乌恰县| 文登市| 扎囊县| 盐山县| 泗洪县| 重庆市| 西贡区| 商都县| 青海省| 明星| 德阳市| 鹿泉市| 慈利县| 齐河县| 叙永县| 金坛市| 日土县| 六枝特区|