国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

代理設(shè)計(jì)模式——靜態(tài)代理和動(dòng)態(tài)代理

這篇具有很好參考價(jià)值的文章主要介紹了代理設(shè)計(jì)模式——靜態(tài)代理和動(dòng)態(tài)代理。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

代理模式

在代理模式(Proxy Pattern)中,一個(gè)類(lèi)代表另一個(gè)類(lèi)的功能。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,在代理模式中,我們創(chuàng)建具有現(xiàn)有對(duì)象的對(duì)象,以便向外界提供功能接口。

意圖:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪(fǎng)問(wèn)。

主要解決:在直接訪(fǎng)問(wèn)對(duì)象時(shí)帶來(lái)的問(wèn)題,比如說(shuō):要訪(fǎng)問(wèn)的對(duì)象在遠(yuǎn)程的機(jī)器上。在面向?qū)ο笙到y(tǒng)中,有些對(duì)象由于某些原因(比如對(duì)象創(chuàng)建開(kāi)銷(xiāo)很大,或者某些操作需要安全控制,或者需要進(jìn)程外的訪(fǎng)問(wèn)),直接訪(fǎng)問(wèn)會(huì)給使用者或者系統(tǒng)結(jié)構(gòu)帶來(lái)很多麻煩,我們可以在訪(fǎng)問(wèn)此對(duì)象時(shí)加上一個(gè)對(duì)此對(duì)象的訪(fǎng)問(wèn)層。

何時(shí)使用:想在訪(fǎng)問(wèn)一個(gè)類(lèi)時(shí)做一些控制。

如何解決:增加中間層。

關(guān)鍵代碼:實(shí)現(xiàn)與被代理類(lèi)組合。

兩種機(jī)制

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

代理設(shè)計(jì)模式——靜態(tài)代理和動(dòng)態(tài)代理,設(shè)計(jì)模式,設(shè)計(jì)模式,代理模式

靜態(tài)代理

定義:代理和被代理對(duì)象在代理之前是確定的,他們都實(shí)現(xiàn)相同的接口或者繼承相同的抽象類(lèi)

兩種實(shí)現(xiàn)機(jī)制

  • 繼承
  • 聚合

模式:

代理設(shè)計(jì)模式——靜態(tài)代理和動(dòng)態(tài)代理,設(shè)計(jì)模式,設(shè)計(jì)模式,代理模式

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

  • 優(yōu)點(diǎn): 擴(kuò)展原功能,不侵入原代碼。
  • 缺點(diǎn):如果通過(guò)繼承方式實(shí)現(xiàn),因?yàn)镴AVA類(lèi)只能繼承一個(gè)父類(lèi),所以需要有多個(gè)代理類(lèi);如果通過(guò)聚合實(shí)現(xiàn),當(dāng)要實(shí)現(xiàn)多個(gè)接口代理時(shí),代碼會(huì)比較臃腫,需要為每個(gè)代理接口編寫(xiě)實(shí)現(xiàn)代碼。

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

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

CGLib

CGLIB(Code Generation Library)是一個(gè)開(kāi)源項(xiàng)目,是一個(gè)強(qiáng)大的,高性能,高質(zhì)量的Code生成類(lèi)庫(kù),它可以在運(yùn)行期擴(kuò)展Java類(lèi)與實(shí)現(xiàn)Java接口。Hibernate用它來(lái)實(shí)現(xiàn)PO(Persistent Object 持久化對(duì)象)字節(jié)碼的動(dòng)態(tài)生成;

jdk和cglib動(dòng)態(tài)代理實(shí)現(xiàn)的區(qū)別

  1. CGLib創(chuàng)建的動(dòng)態(tài)代理對(duì)象性能比JDK創(chuàng)建的動(dòng)態(tài)代理對(duì)象的性能高不少,但是CGLib在創(chuàng)建代理對(duì)象時(shí)所花費(fèi)的時(shí)間卻比JDK多得多,所以對(duì)于單例的對(duì)象,因?yàn)闊o(wú)需頻繁創(chuàng)建對(duì)象,用CGLib合適,反之,使用JDK方式要更為合適一些;
  2. JDK動(dòng)態(tài)代理的對(duì)象必須實(shí)現(xiàn)一個(gè)或多個(gè)接口;
  3. cglib動(dòng)態(tài)代理中生成的字節(jié)碼更加復(fù)雜,生成的代理類(lèi)是委托類(lèi)的子類(lèi),且不能處理被final關(guān)鍵字修飾的方法;
  4. jdk采用反射機(jī)制調(diào)用委托類(lèi)的方法,cglib采用類(lèi)似索引的方式直接調(diào)用委托類(lèi)方法;

代理設(shè)計(jì)模式——靜態(tài)代理和動(dòng)態(tài)代理,設(shè)計(jì)模式,設(shè)計(jì)模式,代理模式

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

核心思想:通過(guò)實(shí)現(xiàn)被代理類(lèi)的所有接口,生成一個(gè)字節(jié)碼文件后構(gòu)造一個(gè)代理對(duì)象,通過(guò)持有反射構(gòu)造被代理類(lèi)的一個(gè)實(shí)例,再通過(guò)invoke反射調(diào)用被代理類(lèi)實(shí)例的方法,來(lái)實(shí)現(xiàn)代理。

缺點(diǎn):JDK動(dòng)態(tài)代理的對(duì)象必須實(shí)現(xiàn)一個(gè)或多個(gè)接口

代理設(shè)計(jì)模式——靜態(tài)代理和動(dòng)態(tài)代理,設(shè)計(jì)模式,設(shè)計(jì)模式,代理模式

代理設(shè)計(jì)模式——靜態(tài)代理和動(dòng)態(tài)代理,設(shè)計(jì)模式,設(shè)計(jì)模式,代理模式

知識(shí)點(diǎn)

  • JDK實(shí)現(xiàn)動(dòng)態(tài)代理需要實(shí)現(xiàn)類(lèi)通過(guò)接口定義業(yè)務(wù)方法
  • JDK生成的代理類(lèi)以"$Proxy"為開(kāi)頭進(jìn)行命名
  • JDK代理生成的代理類(lèi)的Method在static靜態(tài)代碼塊中進(jìn)行初始化;
  • public接口生成的代理類(lèi)package為"com.sun.proxy";
  • JDK動(dòng)態(tài)代理需要實(shí)現(xiàn)InvocationHandler接口;

代碼:

package com.quancheng;

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

public class DynamicProxy {
    public static void main(String[] args) {
        Student stu = new Student();
        CusInvocationHandler handler = new CusInvocationHandler(stu);
        Play instance = (Play) Proxy.newProxyInstance(stu.getClass().getClassLoader(), stu.getClass().getInterfaces(), handler);
        instance.play();
    }
}

class CusInvocationHandler implements InvocationHandler {
    private Object target;

    public CusInvocationHandler(Object object) {
        this.target = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.err.println("代理方法處理");
        return method.invoke(target, args);
    }
}

interface Play {
    void play();
}

class Student implements Play {

    @Override
    public void play() {
        System.err.println("student ====>");
    }
}

生成的代理類(lèi)示例:

import dynamic.proxy.UserService;  
import java.lang.reflect.*;  

public final class $Proxy11 extends Proxy  
    implements UserService  
{  

    // 構(gòu)造方法,參數(shù)就是剛才傳過(guò)來(lái)的MyInvocationHandler類(lèi)的實(shí)例  
    public $Proxy11(InvocationHandler invocationhandler)  
    {  
        super(invocationhandler);  
    }  

    public final boolean equals(Object obj)  
    {  
        // 省略
    }  

    /** 
     * 被代理的方法 
     */  
    public final void add()  
    {  
        try  
        {  
            // 實(shí)際上就是調(diào)用MyInvocationHandler的public Object invoke(Object proxy, Method method, Object[] args)方法,第二個(gè)問(wèn)題就解決了  
            super.h.invoke(this, m3, null);  
            return;  
        }  
        catch(Error _ex) { }  
        catch(Throwable throwable)  
        {  
            throw new UndeclaredThrowableException(throwable);  
        }  
    }  

    public final int hashCode()  
    {  
        // 省略
    }  

    public final String toString()  
    {  
        // 省略
    }  

    private static Method m1;  
    private static Method m3;  
    private static Method m0;  
    private static Method m2;  

    // 在靜態(tài)代碼塊中獲取了4個(gè)方法:Object中的equals方法、UserService中的add方法、Object中的hashCode方法、Object中toString方法  
    static   
    {  
        try  
        {  
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] {  
                Class.forName("java.lang.Object")  
            });  
            m3 = Class.forName("dynamic.proxy.UserService").getMethod("add", new Class[0]);  
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);  
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);  
        }  
        catch(NoSuchMethodException nosuchmethodexception)  
        {  
            throw new NoSuchMethodError(nosuchmethodexception.getMessage());  
        }  
        catch(ClassNotFoundException classnotfoundexception)  
        {  
            throw new NoClassDefFoundError(classnotfoundexception.getMessage());  
        }  
    }  
}

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

核心思想:CGLib采用了非常底層的字節(jié)碼技術(shù),其原理是通過(guò)字節(jié)碼技術(shù)為一個(gè)類(lèi)創(chuàng)建子類(lèi)(CGLib底層是通過(guò)繼承實(shí)現(xiàn)的動(dòng)態(tài)代理),并在子類(lèi)中采用方法攔截的技術(shù)攔截所有父類(lèi)方法的調(diào)用,順勢(shì)織入橫切邏輯。JDK動(dòng)態(tài)代理與CGLib動(dòng)態(tài)代理均是實(shí)現(xiàn)Spring AOP的基礎(chǔ);底層:使用一個(gè)小而快的字節(jié)碼處理框架ASM(Java字節(jié)碼操控框架),來(lái)轉(zhuǎn)換字節(jié)碼并生成新的類(lèi)

缺點(diǎn):不能代理final修飾的類(lèi)

示例代碼:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-635388.html

//被代理的類(lèi)即目標(biāo)對(duì)象
public class A {
    public void execute(){
        System.out.println("執(zhí)行A的execute方法...");
    }
}

//代理類(lèi)
public class CGLibProxy implements MethodInterceptor {

    /**
     * 被代理的目標(biāo)類(lèi)
     */
    private A target;

    public CGLibProxy(A target) {
        super();
        this.target = target;
    }

    /**
     * 創(chuàng)建代理對(duì)象
     * @return
     */
    public A createProxy(){
        // 使用CGLIB生成代理:
        // 1.聲明增強(qiáng)類(lèi)實(shí)例,用于生產(chǎn)代理類(lèi)
        Enhancer enhancer = new Enhancer();
        // 2.設(shè)置被代理類(lèi)字節(jié)碼,CGLIB根據(jù)字節(jié)碼生成被代理類(lèi)的子類(lèi)
        enhancer.setSuperclass(target.getClass());
        // 3.//設(shè)置回調(diào)函數(shù),即一個(gè)方法攔截
        enhancer.setCallback(this);
        // 4.創(chuàng)建代理:
        return (A) enhancer.create();
    }

    /**
     * 回調(diào)函數(shù)
     * @param proxy 代理對(duì)象
     * @param method 委托類(lèi)方法
     * @param args 方法參數(shù)
     * @param methodProxy 每個(gè)被代理的方法都對(duì)應(yīng)一個(gè)MethodProxy對(duì)象,
     *                    methodProxy.invokeSuper方法最終調(diào)用委托類(lèi)(目標(biāo)類(lèi))的原始方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
   //過(guò)濾不需要該業(yè)務(wù)的方法
      if("execute".equals(method.getName())) {
          //調(diào)用前驗(yàn)證權(quán)限(動(dòng)態(tài)添加其他要執(zhí)行業(yè)務(wù))
          AuthCheck.authCheck();

          //調(diào)用目標(biāo)對(duì)象的方法(執(zhí)行A對(duì)象即被代理對(duì)象的execute方法)
          Object result = methodProxy.invokeSuper(proxy, args);

          //記錄日志數(shù)據(jù)(動(dòng)態(tài)添加其他要執(zhí)行業(yè)務(wù))
          Report.recordLog();

          return result;
      }else if("delete".equals(method.getName())){
          //.....
          return methodProxy.invokeSuper(proxy, args);
      }
      //如果不需要增強(qiáng)直接執(zhí)行原方法
      return methodProxy.invokeSuper(proxy, args);

    }
}

到了這里,關(guān)于代理設(shè)計(jì)模式——靜態(tài)代理和動(dòng)態(tài)代理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 設(shè)計(jì)模式的使用——模板方法模式+動(dòng)態(tài)代理模式

    設(shè)計(jì)模式的使用——模板方法模式+動(dòng)態(tài)代理模式

    一、需求介紹 ??現(xiàn)有自己寫(xiě)的的一套審批流程邏輯,由于代碼重構(gòu),需要把以前的很多業(yè)務(wù)加上審批的功能,再執(zhí)行完審批與原有業(yè)務(wù)之后,生成一個(gè)任務(wù),然后再統(tǒng)一處理一個(gè)任務(wù)(本來(lái)是通過(guò)數(shù)據(jù)庫(kù)作業(yè)去處理的,后來(lái)說(shuō)這個(gè)任務(wù)要馬上去處理,只能去統(tǒng)一添加一個(gè)處

    2024年02月10日
    瀏覽(27)
  • 代理模式--靜態(tài)代理和動(dòng)態(tài)代理

    代理模式--靜態(tài)代理和動(dòng)態(tài)代理

    定義:代理模式就是代替對(duì)象具備真實(shí)對(duì)象的功能,并代替真實(shí)對(duì)象完成相應(yīng)的操作并且在不改變真實(shí)對(duì)象源代碼的情況下擴(kuò)展其功能,在某些情況下,?個(gè)對(duì)象不適合或者不能直接引?另?個(gè)對(duì)象,?代理對(duì)象可以在客戶(hù)端和?標(biāo)對(duì)象之間起到中介的作? 使用代理模式可以

    2024年02月15日
    瀏覽(24)
  • Java代理模式——靜態(tài)代理與動(dòng)態(tài)代理

    Java代理模式——靜態(tài)代理與動(dòng)態(tài)代理

    代理模式允許你為其他對(duì)象提供一個(gè)代理,以控制對(duì)這個(gè)對(duì)象的訪(fǎng)問(wèn)。代理模式在不改變實(shí)際對(duì)象的情況下,可以在訪(fǎng)問(wèn)對(duì)象時(shí)添加額外的功能。 可以理解為代理模式為被代理對(duì)象創(chuàng)造了一個(gè)替身,調(diào)用者可以通過(guò)這個(gè)替身去實(shí)現(xiàn)這個(gè)被代理對(duì)象的功能,這個(gè)替身也可以為被

    2024年02月13日
    瀏覽(21)
  • 代理模式:靜態(tài)代理+JDK/CGLIB 動(dòng)態(tài)代理

    代理模式:靜態(tài)代理+JDK/CGLIB 動(dòng)態(tài)代理

    代理模式是一種比較好理解的設(shè)計(jì)模式。簡(jiǎn)單來(lái)說(shuō)就是 我們使用代理對(duì)象來(lái)代替對(duì)真實(shí)對(duì)象(real object)的訪(fǎng)問(wèn),這樣就可以在不修改原目標(biāo)對(duì)象的前提下,提供額外的功能操作,擴(kuò)展目標(biāo)對(duì)象的功能。 代理模式的主要作用是擴(kuò)展目標(biāo)對(duì)象的功能,比如說(shuō)在目標(biāo)對(duì)象的某個(gè)方法

    2024年02月13日
    瀏覽(24)
  • 溫故知新之:代理模式,靜態(tài)代理和動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理)

    溫故知新之:代理模式,靜態(tài)代理和動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理)

    代理模式可以在不修改被代理對(duì)象的基礎(chǔ)上,通過(guò)擴(kuò)展代理類(lèi),進(jìn)行一些功能的附加與增強(qiáng)。 靜態(tài)代理 是一種代理模式的實(shí)現(xiàn)方式,它在編譯期間就已經(jīng)確定了代理對(duì)象,需要為每一個(gè)被代理對(duì)象創(chuàng)建一個(gè)代理類(lèi)。靜態(tài)代理的實(shí)現(xiàn)比較簡(jiǎn)單,但是每個(gè)被代理對(duì)象都需要?jiǎng)?chuàng)建

    2024年02月11日
    瀏覽(30)
  • 代理模式【靜態(tài)代理和動(dòng)態(tài)代理實(shí)現(xiàn)業(yè)務(wù)功能擴(kuò)展】

    代理模式【靜態(tài)代理和動(dòng)態(tài)代理實(shí)現(xiàn)業(yè)務(wù)功能擴(kuò)展】

    我們?cè)诓恍薷臉I(yè)務(wù)的情況下想要給它增加一些功能,這就需要使用代理模式。 我們不會(huì)在原有業(yè)務(wù)上直接修改,為了避免修改導(dǎo)致程序不可逆轉(zhuǎn)的破壞。 三種角色:抽象角色-接口、真實(shí)角色-實(shí)現(xiàn)類(lèi)和代理角色-代理類(lèi)。 真實(shí)角色和代理角色繼承的是同一個(gè)抽象角色接口!

    2024年02月16日
    瀏覽(25)
  • Java 代理模式詳解,靜態(tài)代理與動(dòng)態(tài)代理的區(qū)別及優(yōu)缺點(diǎn)

    代理模式是一種常用的設(shè)計(jì)模式,它允許通過(guò)引入一個(gè)代理對(duì)象來(lái)控制對(duì)目標(biāo)對(duì)象的訪(fǎng)問(wèn)。在Java中,代理模式被廣泛應(yīng)用,它可以提供額外的功能,如權(quán)限檢查、緩存、日志記錄等,同時(shí)還能在不修改目標(biāo)對(duì)象的情況下對(duì)其進(jìn)行擴(kuò)展。 代理模式(Proxy Pattern)是指通過(guò)代理對(duì)象

    2024年02月11日
    瀏覽(27)
  • Java設(shè)計(jì)模式 (三) 代理設(shè)計(jì)模式

    什么是代理設(shè)計(jì)模式? 代理設(shè)計(jì)模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它允許創(chuàng)建一個(gè)代理對(duì)象,用于控制對(duì)其他對(duì)象的訪(fǎng)問(wèn)。代理模式通常用于在訪(fǎng)問(wèn)對(duì)象時(shí)添加一些附加操作,而不是直接訪(fǎng)問(wèn)真實(shí)對(duì)象。代理模式可以在不改變?cè)碱?lèi)代碼的情況下,通過(guò)引入代理類(lèi)來(lái)增強(qiáng)功能。 代

    2024年02月12日
    瀏覽(26)
  • 【設(shè)計(jì)模式】-代理模式

    在軟件開(kāi)發(fā)中,經(jīng)常遇到需要對(duì)某個(gè)對(duì)象進(jìn)行控制或者監(jiān)控的場(chǎng)景。而直接修改對(duì)象的代碼可能使代碼變得復(fù)雜且難以維護(hù)。這時(shí),使用代理模式(Proxy Pattern)可以很好地解決這個(gè)問(wèn)題。 ?????????代理模式是一種結(jié)構(gòu)型設(shè)計(jì)模式, 通過(guò)引入一個(gè)代理對(duì)象來(lái)替代原始對(duì)象

    2024年02月13日
    瀏覽(28)
  • 設(shè)計(jì)模式-代理模式

    ● 為對(duì)象提供一個(gè)代理類(lèi),增強(qiáng)該對(duì)象的方法,控制對(duì)這個(gè)對(duì)象的訪(fǎng)問(wèn) ● 靜態(tài)代理和動(dòng)態(tài)代理:靜態(tài)代理就是編譯的時(shí)候就已經(jīng)確定,而動(dòng)態(tài)代理就是運(yùn)行時(shí)才會(huì)生成 緩存代理 ● 提供數(shù)據(jù)的緩存功能,避免數(shù)據(jù)庫(kù)重復(fù)查詢(xún) 實(shí)踐 定義數(shù)據(jù)查詢(xún)的接口 接口實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)接口

    2024年02月11日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包