www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]什么是代理 代理模式是常用的java設(shè)計(jì)模式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過(guò)濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等。代理類與委托類之間通常會(huì)存在關(guān)聯(lián)關(guān)系,一個(gè)代理類的對(duì)象與一個(gè)委托類的對(duì)象關(guān)聯(lián)

終于有人把 java代理 講清楚了,萬(wàn)字詳解!

什么是代理

代理模式是常用的java設(shè)計(jì)模式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過(guò)濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等。代理類與委托類之間通常會(huì)存在關(guān)聯(lián)關(guān)系,一個(gè)代理類的對(duì)象與一個(gè)委托類的對(duì)象關(guān)聯(lián),代理類的對(duì)象本身并不真正實(shí)現(xiàn)服務(wù),而是通過(guò)調(diào)用委托類的對(duì)象的相關(guān)方法,來(lái)提供特定的服務(wù)。

代理其實(shí)不僅僅是在軟件開(kāi)發(fā)領(lǐng)域,在我們的日常生活中也是時(shí)常可見(jiàn)。比如某p2p老板突然攜款帶著小姨子跑路了,可憐了下面一堆的程序員背負(fù)一身房貸,上有老下有小,程序員只能被迫去申請(qǐng)勞動(dòng)仲裁,勞動(dòng)局就會(huì)為其指派一位代理律師全權(quán)負(fù)責(zé)程序員的仲裁事宜(PS:p2p跑路仲裁拿回工資的可能性非常低,沒(méi)讓你把工資退回就算好的了)。那這里面就是使用了代理模式,因?yàn)樵趧趧?dòng)仲裁這個(gè)活動(dòng)中,代理律師會(huì)全權(quán)代理程序員。比如:房東要將房子出售,于是到房地產(chǎn)中介公司找一個(gè)中介(代理),由他來(lái)幫房東完成銷售房屋,簽訂合同、網(wǎng)簽、貸款過(guò)戶等等事宜。

代理模式

終于有人把 java代理 講清楚了,萬(wàn)字詳解!這是常見(jiàn)代理模式常見(jiàn)的 UML 示意圖。 需要注意的有下面幾點(diǎn):

  1. 用戶只關(guān)心接口功能,而不在乎誰(shuí)提供了功能。上圖中接口是  Subject。
  2. 接口真正實(shí)現(xiàn)者是上圖的  RealSubject,但是它不與用戶直接接觸,而是通過(guò)代理。
  3. 代理就是上圖中的  Proxy,由于它實(shí)現(xiàn)了  Subject 接口,所以它能夠直接與用戶接觸。
  4. 用戶調(diào)用  Proxy 的時(shí)候, Proxy 內(nèi)部調(diào)用了  RealSubject。所以, Proxy 是中介者,它可以增強(qiáng)  RealSubject 操作。
  • 代理又可以分為靜態(tài)代理和動(dòng)態(tài)代理兩種。我們先來(lái)看下靜態(tài)代理。

靜態(tài)代理

電影是電影公司委托給影院進(jìn)行播放的,但是影院可以在播放電影的時(shí)候,產(chǎn)生一些自己的經(jīng)濟(jì)收益,比如提供按摩椅,娃娃機(jī)(這個(gè)每次去電影院都會(huì)嘗試下,基本上是夾不起來(lái),有木有大神可以傳授下訣竅),賣爆米花、飲料(貴的要死,反正吃不起)等。我們平常去電影院看電影的時(shí)候,在電影開(kāi)始的階段是不是經(jīng)常會(huì)放廣告呢?然后在影片開(kāi)始結(jié)束時(shí)播放一些廣告。 下面我們通過(guò)代碼來(lái)模擬下電影院這一系列的賺錢操作。 首先得有一個(gè)接口,通用的接口是代理模式實(shí)現(xiàn)的基礎(chǔ)。這個(gè)接口我們命名為 Movie,代表電影播放的能力。

package com.workit.demo.proxy;

public interface Movie {
    void play();
}

  • 接下來(lái)我們要?jiǎng)?chuàng)建一個(gè)真正的實(shí)現(xiàn)這個(gè)  Movie 接口的類,和一個(gè)實(shí)現(xiàn)該接口的代理類。 真正的類 《美國(guó)隊(duì)長(zhǎng)》電影:
package com.workit.demo.proxy;

public class CaptainAmericaMovie implements Movie {
    @Override
    public void play() {
        System.out.println("普通影廳正在播放的電影是《美國(guó)隊(duì)長(zhǎng)》");
    }
}

代理類:

package com.workit.demo.proxy;

public class MovieStaticProxy implements Movie {
    Movie movie;

    public MovieStaticProxy(Movie movie) {
        this.movie = movie;
    }

    @Override
    public void play() {
        playStart();
        movie.play();
        playEnd();
    }

    public void playStart() {
        System.out.println("電影開(kāi)始前正在播放廣告");
    }
    public void playEnd() {
        System.out.println("電影結(jié)束了,接續(xù)播放廣告");
    }
}


測(cè)試類:

package com.workit.demo.proxy;

package com.workit.demo.proxy;

public class StaticProxyTest {
    public static void main(String[] args) {
        Movie captainAmericaMovie = new CaptainAmericaMovie();
        Movie movieStaticProxy = new MovieStaticProxy(captainAmericaMovie);
        movieStaticProxy.play();

    }
}

運(yùn)行結(jié)果:

電影開(kāi)始前正在播放廣告
正在播放的電影是《美國(guó)隊(duì)長(zhǎng)》
電影結(jié)束了,接續(xù)播放廣告

現(xiàn)在可以看到,代理模式可以在不修改被代理對(duì)象的基礎(chǔ)上,通過(guò)擴(kuò)展代理類,進(jìn)行一些功能的附加與增強(qiáng)。值得注意的是,代理類和被代理類應(yīng)該共同實(shí)現(xiàn)一個(gè)接口,或者是共同繼承某個(gè)類。這個(gè)就是是靜態(tài)代理的內(nèi)容,為什么叫做靜態(tài)呢?因?yàn)樗念愋褪鞘孪阮A(yù)定好的,比如上面代碼中的 MovieStaticProxy 這個(gè)類。

優(yōu)點(diǎn)
  • 代理模式在客戶端與目標(biāo)對(duì)象之間起到一個(gè)中介作用和保護(hù)目標(biāo)對(duì)象的作用
  • 代理對(duì)象可以擴(kuò)展目標(biāo)對(duì)象的功能
  • 代理模式能將客戶端與目標(biāo)對(duì)象分離,在一定程度上降低了系統(tǒng)的耦合度。
缺點(diǎn)
  • 代理對(duì)象需要與目標(biāo)對(duì)象實(shí)現(xiàn)一樣的接口,所以會(huì)有很多代理類,類太多.同時(shí),一旦接口增加方法,目標(biāo)對(duì)象與代理對(duì)象都要維護(hù)。

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

與靜態(tài)代理類對(duì)照的是動(dòng)態(tài)代理類,動(dòng)態(tài)代理類的字節(jié)碼在程序運(yùn)行時(shí)由Java反射機(jī)制動(dòng)態(tài)生成,無(wú)需程序員手工編寫(xiě)它的源代碼。動(dòng)態(tài)代理類不僅簡(jiǎn)化了編程工作,而且提高了軟件系統(tǒng)的可擴(kuò)展性,因?yàn)镴ava 反射機(jī)制可以生成任意類型的動(dòng)態(tài)代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 接口提供了生成動(dòng)態(tài)代理類的能力。

  • 接著上面的例子,剛看完《美國(guó)隊(duì)長(zhǎng)》不過(guò)癮,還想繼續(xù)去看一場(chǎng)《鋼鐵俠》。一直在普通影廳看電影覺(jué)得沒(méi)啥意思,那就趕緊去VIP影廳( 至今不知道長(zhǎng)啥樣子)體驗(yàn)一把。既然 實(shí)體店沒(méi)體驗(yàn)過(guò)那就用代碼來(lái)體驗(yàn)一次吧。創(chuàng)建一個(gè)VIPMovie電影接口
package com.workit.demo.proxy;
public interface VIPMovie {
    void vipPlay();
}

緊接著創(chuàng)建一個(gè)VIP影廳的播放實(shí)現(xiàn)類

package com.workit.demo.proxy;

public class IronManVIPMovie implements VIPMovie {
    @Override
    public void vipPlay() {
        System.out.println("VI影廳正在播放的電影是《鋼鐵俠》");
    }
}

如果按照靜態(tài)代理我們是不是又要?jiǎng)?chuàng)建一個(gè)VIP影廳播放的代理實(shí)現(xiàn)類,這種方式我們就不演示了。下面我們來(lái)看看通過(guò)動(dòng)態(tài)代理怎么來(lái)實(shí)現(xiàn)吧。

package com.workit.demo.proxy;

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

public class MyInvocationHandler implements InvocationHandler {

    private Object object;

    public MyInvocationHandler(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        playStart();
        Object invoke = method.invoke(object, args);
        playEnd();
        return invoke;
    }

    public void playStart() {
        System.out.println("電影開(kāi)始前正在播放廣告");
    }
    public void playEnd() {
        System.out.println("電影結(jié)束了,接續(xù)播放廣告");
    }
}

MyInvocationHandler實(shí)現(xiàn)了 InvocationHandler 這個(gè)類,這個(gè)類是什么意思呢?大家不要慌張,下面我會(huì)解釋。然后,我們就可以在VIP影廳看電影了。

package com.workit.demo.proxy;

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

public class DynamicProxyTest {
    public static void main(String[] args) {
        IronManVIPMovie ironManVIPMovie = new IronManVIPMovie();
        InvocationHandler invocationHandler = new MyInvocationHandler(ironManVIPMovie);
        VIPMovie dynamicProxy = (VIPMovie) Proxy.newProxyInstance(IronManVIPMovie.class.getClassLoader(),
                IronManVIPMovie.class.getInterfaces(), invocationHandler);
        dynamicProxy.vipPlay();
    }
}

輸出結(jié)果:

電影開(kāi)始前正在播放廣告
VI影廳正在播放的電影是《鋼鐵俠》
電影結(jié)束了,接續(xù)播放廣告

看到?jīng)]有,我們并沒(méi)有像靜態(tài)代理那樣為 VIPMovie接口實(shí)現(xiàn)一個(gè)代理類,但最終它仍然實(shí)現(xiàn)了相同的功能,這其中的差別,就是之前討論的動(dòng)態(tài)代理所謂“動(dòng)態(tài)”的原因。 我們順帶把《美國(guó)隊(duì)長(zhǎng)》也用動(dòng)態(tài)代理實(shí)現(xiàn)下吧。

package com.workit.demo.proxy;

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

public class DynamicProxyTest {
    public static void main(String[] args) {
        // VIP 影廳《鋼鐵俠》
        IronManVIPMovie ironManVIPMovie = new IronManVIPMovie();
        InvocationHandler invocationHandler = new MyInvocationHandler(ironManVIPMovie);
        VIPMovie dynamicProxy = (VIPMovie) Proxy.newProxyInstance(IronManVIPMovie.class.getClassLoader(),
                IronManVIPMovie.class.getInterfaces(), invocationHandler);
        dynamicProxy.vipPlay();
        
        // 普通影廳《美國(guó)隊(duì)長(zhǎng)》
        CaptainAmericaMovie captainAmericaMovie = new CaptainAmericaMovie();
        InvocationHandler invocationHandler1 = new MyInvocationHandler(captainAmericaMovie);
        Movie dynamicProxy1 = (Movie) Proxy.newProxyInstance(CaptainAmericaMovie.class.getClassLoader(),
                CaptainAmericaMovie.class.getInterfaces(), invocationHandler1);
        dynamicProxy1.play();
    }
}

輸出結(jié)果:

電影開(kāi)始前正在播放廣告
VI影廳正在播放的電影是《鋼鐵俠》
電影結(jié)束了,接續(xù)播放廣告
電影開(kāi)始前正在播放廣告
正在播放的電影是《美國(guó)隊(duì)長(zhǎng)》
電影結(jié)束了,接續(xù)播放廣告

我們通過(guò) Proxy.newProxyInstance() 方法,卻產(chǎn)生了 Movie和 VIPMovie兩種接口的實(shí)現(xiàn)類代理,這就是動(dòng)態(tài)代理的魔力。

JDK動(dòng)態(tài)代理到底是怎么實(shí)現(xiàn)的呢

動(dòng)態(tài)代碼涉及了一個(gè)非常重要的類 Proxy。正是通過(guò) Proxy 的靜態(tài)方法 newProxyInstance 才會(huì)動(dòng)態(tài)創(chuàng)建代理。具體怎么去創(chuàng)建代理類就不分析了,感興趣的可以去看下源碼。我們直接看下生成的代理類。 如何查看生成的代理類? 在生成代理類之前加上以下代碼(我用的jdk1.8):

 //新版本 jdk產(chǎn)生代理類   
 System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles""true");

如果上述代碼加上不生效可以考慮加下下面的代碼:

// 老版本jdk
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles""true");
//  該設(shè)置用于輸出cglib動(dòng)態(tài)代理產(chǎn)生的類
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\class");  

代碼如下:

  public static void main(String[] args) {
        //新版本 jdk產(chǎn)生代理類
       System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles""true");
        // VIP 影廳《鋼鐵俠》
        IronManVIPMovie ironManVIPMovie = new IronManVIPMovie();
        InvocationHandler invocationHandler = new MyInvocationHandler(ironManVIPMovie);
        VIPMovie dynamicProxy = (VIPMovie) Proxy.newProxyInstance(IronManVIPMovie.class.getClassLoader(),
                IronManVIPMovie.class.getInterfaces(), invocationHandler);
        dynamicProxy.vipPlay();

        // 普通影廳《美國(guó)隊(duì)長(zhǎng)》
        CaptainAmericaMovie captainAmericaMovie = new CaptainAmericaMovie();
        InvocationHandler invocationHandler1 = new MyInvocationHandler(captainAmericaMovie);
        Movie dynamicProxy1 = (Movie) Proxy.newProxyInstance(CaptainAmericaMovie.class.getClassLoader(),
                CaptainAmericaMovie.class.getInterfaces(), invocationHandler1);
        dynamicProxy1.play();
        System.out.println("VIP 影廳《鋼鐵俠》代理類:"+dynamicProxy.getClass());
        System.out.println("普通影廳《美國(guó)隊(duì)長(zhǎng)》:"+dynamicProxy1.getClass());
    }

我們可以看到結(jié)果

電影開(kāi)始前正在播放廣告
VI影廳正在播放的電影是《鋼鐵俠》
電影結(jié)束了,接續(xù)播放廣告
電影開(kāi)始前正在播放廣告
正在播放的電影是《美國(guó)隊(duì)長(zhǎng)》
電影結(jié)束了,接續(xù)播放廣告
VIP 影廳《鋼鐵俠》代理類:class com.sun.proxy.$Proxy0
普通影廳《美國(guó)隊(duì)長(zhǎng)》:class com.sun.proxy.$Proxy1

產(chǎn)生了兩個(gè)代理類分別是$Proxy0$Proxy1。 下面?zhèn)儊?lái)看下"鋼鐵俠"的代理類$Proxy0

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.sun.proxy;

import com.workit.demo.proxy.VIPMovie;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements VIPMovie {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void vipPlay() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.workit.demo.proxy.VIPMovie").getMethod("vipPlay");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
},

通過(guò)上述代碼我們可以看到 $Proxy0 extends Proxy implements VIPMovie繼承了Proxy 且實(shí)現(xiàn)了VIPMovie接口,這也就是為什么jdk動(dòng)態(tài)代理必須基于接口,java 是單繼承的。 然后再看下代理類實(shí)現(xiàn)的方法:

 public final void vipPlay() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

這個(gè)supper.h.invoke Proxy中的h的invoke方法,即InvocationHandler.invoke也就是上面 MyInvocationHandler.invoke方法,至此整個(gè)流程就清晰了。這就是jdk的動(dòng)態(tài)代理。

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

上面說(shuō)jdk動(dòng)態(tài)代理只能基于接口,那么如果是類要?jiǎng)討B(tài)代理怎么辦呢?cglib動(dòng)態(tài)代理就可解決關(guān)于類的動(dòng)態(tài)代理。 下面我們來(lái)創(chuàng)建一個(gè)“《美國(guó)隊(duì)長(zhǎng)2》”

package com.workit.demo.proxy;

public class CaptainAmerica2MovieImpl {

    public void play(){
        System.out.println("正在播放的電影是《美國(guó)隊(duì)長(zhǎng)2》");
    }
}

引入cglib pom依賴

<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

創(chuàng)建一個(gè)自定義MethodInterceptor。

package com.workit.demo.proxy;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibProxyInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        playStart();
        Object object = methodProxy.invokeSuper(o, objects);
        playEnd();
        return object;
    }

    public void playStart() {
        System.out.println("電影開(kāi)始前正在播放廣告");
    }

    public void playEnd() {
        System.out.println("電影結(jié)束了,接續(xù)播放廣告");
    }
}

測(cè)試類

package com.workit.demo.proxy;

import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;

public class CglibProxyTest {
    public static void main(String[] args) {
        // //在指定目錄下生成動(dòng)態(tài)代理類
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\class");
        //創(chuàng)建Enhancer對(duì)象,類似于JDK動(dòng)態(tài)代理的Proxy類,下一步就是設(shè)置幾個(gè)參數(shù)
        Enhancer enhancer = new Enhancer();
        //設(shè)置目標(biāo)類的字節(jié)碼文件
        enhancer.setSuperclass(CaptainAmerica2MovieImpl.class);
        //設(shè)置回調(diào)函數(shù)
        enhancer.setCallback(new CglibProxyInterceptor());
        //這里的creat方法就是正式創(chuàng)建代理類
        CaptainAmerica2MovieImpl captainAmerica2Movie = (CaptainAmerica2MovieImpl)enhancer.create();
        //調(diào)用代理類的play方法
        captainAmerica2Movie.play();
        System.out.println("cglib動(dòng)態(tài)代理《美國(guó)隊(duì)長(zhǎng)2》:"+captainAmerica2Movie.getClass());
    }
}

輸出結(jié)果:

電影開(kāi)始前正在播放廣告
正在播放的電影是《美國(guó)隊(duì)長(zhǎng)2
電影結(jié)束了,接續(xù)播放廣告
cglib動(dòng)態(tài)代理《美國(guó)隊(duì)長(zhǎng)2》:class com.workit.demo.proxy.CaptainAmerica2MovieImpl$$EnhancerByCGLIB$$5c3ddcfe

我們看下最終創(chuàng)建的代理類生成的play方法

public class CaptainAmerica2MovieImpl$$EnhancerByCGLIB$$5c3ddcfe extends CaptainAmerica2MovieImpl implements Factory {
  public final void play() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$play$0$Method, CGLIB$emptyArgs, CGLIB$play$0$Proxy);
        } else {
            super.play();
        }
    }

從代理對(duì)象反編譯源碼可以知道,代理對(duì)象繼承于CaptainAmerica2MovieImpl ,攔截器調(diào)用intercept()方法, intercept()方法由自定義CglibProxyInterceptor實(shí)現(xiàn),所以,最后調(diào)用CglibProxyInterceptor中的intercept()方法,從而完成了由代理對(duì)象訪問(wèn)到目標(biāo)對(duì)象的動(dòng)態(tài)代理實(shí)現(xiàn)。

  • CGlib是一個(gè)強(qiáng)大的,高性能,高質(zhì)量的Code生成類庫(kù)。它可以在運(yùn)行期擴(kuò)展Java類與實(shí)現(xiàn)Java接口。
  • 用CGlib生成代理類是目標(biāo)類的子類。
  • 用CGlib生成 代理類不需要接口。
  • 用CGLib生成的代理類重寫(xiě)了父類的各個(gè)方法。
  • 攔截器中的intercept方法內(nèi)容正好就是代理類中的方法體。

總結(jié)

  • 代理分為靜態(tài)代理和動(dòng)態(tài)代理兩種。
  • 靜態(tài)代理,代理類需要自己編寫(xiě)代碼寫(xiě)成。
  • 動(dòng)態(tài)代理有jdk和cglib,代理類通過(guò)  Proxy.newInstance()或者 ASM 生成。
  • 靜態(tài)代理和動(dòng)態(tài)代理的區(qū)別是在于要不要開(kāi)發(fā)者自己定義 Proxy 類。 動(dòng)態(tài)代理通過(guò)  Proxy 動(dòng)態(tài)生成  proxy class,但是它也指定了一個(gè)  InvocationHandler 或者  MethodInterceptor的實(shí)現(xiàn)類。
  • 代理模式本質(zhì)上的目的是為了增強(qiáng)現(xiàn)有代碼的功能。

結(jié)束

  • 由于自己才疏學(xué)淺,難免會(huì)有紕漏,假如你發(fā)現(xiàn)了錯(cuò)誤的地方,還望留言給我指出來(lái),我會(huì)對(duì)其加以修正。
  • 如果你覺(jué)得文章還不錯(cuò),你的轉(zhuǎn)發(fā)、分享、贊賞、點(diǎn)贊、留言就是對(duì)我最大的鼓勵(lì)。
  • 感謝您的閱讀,十分歡迎并感謝您的關(guān)注。

https://blog.csdn.net/m0_37314675/article/details/77850967 https://www.cnblogs.com/cC-Zhou/p/9525638.html https://www.jianshu.com/p/4539e6d9f337

特別推薦一個(gè)分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒(méi)關(guān)注的小伙伴,可以長(zhǎng)按關(guān)注一下:

終于有人把 java代理 講清楚了,萬(wàn)字詳解!

長(zhǎng)按訂閱更多精彩▼

終于有人把 java代理 講清楚了,萬(wàn)字詳解!

如有收獲,點(diǎn)個(gè)在看,誠(chéng)摯感謝

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉
關(guān)閉