最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

2023年再不會動態(tài)代理,就要被淘汰了

2023-06-24 18:18 作者:取個名字吧一個就好  | 我要投稿

代理模式

一、引言

Spring 中,最重要的應(yīng)該當(dāng)屬 IOCAOP 了,IOC 的源碼流程還比較簡單,但 AOP 的流程就較為抽象了。

其中,AOP 中代理模式的重要性不言而喻,但對于沒了解過代理模式的人來說,痛苦至極

于是,我就去看了動態(tài)代理的實現(xiàn),發(fā)現(xiàn)網(wǎng)上大多數(shù)文章講的都是不清不楚,甚至講了和沒講似的,讓我極其難受

本著咱們方向主打的就是源碼,直接從從源碼角度講述一下 代理模式

兄弟們系好安全帶,準(zhǔn)備發(fā)車!

注意:本文篇幅較長,請留出較長時間來閱讀

二、定義

代理模式的定義:由于某些原因需要給某對象提供一個代理以控制對該對象的訪問。這時,訪問對象不適合或者不能直接引用目標(biāo)對象,代理對象作為訪問對象和目標(biāo)對象之間的中介。

舉個生活中常見的例子:客戶想買房,房東有很多房,提供賣房服務(wù),但房東不會帶客戶看房,于是客戶通過中介買房。

這時候?qū)τ诜繓|來說,不直接和客戶溝通,而是交于中介進(jìn)行代理

對于中介來說,她也會在原有的基礎(chǔ)上收取一定的中介費(fèi)

三、靜態(tài)代理

我們創(chuàng)建 Landlord 接口如下:

java復(fù)制代碼public interface Landlord { ?? ?// 出租房子 ?? ?void apartmentToRent(); }

創(chuàng)建其實現(xiàn)類 HangZhouLandlord 代表杭州房東出租房子

java復(fù)制代碼public class HangZhouLandlord implements Landlord { ?? ?@Override ?? ?public void apartmentToRent() { ?? ? ? ?System.out.println("杭州房東出租房子"); ?? ?} }

創(chuàng)建代理類 LandlordProxy,代表中介服務(wù)

java復(fù)制代碼public class LandlordProxy { ? ? ?public Landlord landlord; ? ? ?public LandlordProxy(Landlord landlord) { ?? ? ? ?this.landlord = landlord; ?? ?} ? ? ?public void apartmentToRent() { ?? ? ? ?apartmentToRentBefore(); ?? ? ? ?landlord.apartmentToRent(); ?? ? ? ?apartmentToRentAfter(); ?? ?} ? ? ?public void apartmentToRentBefore() { ?? ? ? ?System.out.println("出租房前,收取中介費(fèi)"); ?? ?} ? ? ?public void apartmentToRentAfter() { ?? ? ? ?System.out.println("出租房后,簽訂合同"); ?? ?} }

創(chuàng)建最終測試:

java復(fù)制代碼public class JavaMain { ?? ?public static void main(String[] args) { ?? ? ? ?Landlord landlord = new HangZhouLandlord(); ? ? ? ? ?LandlordProxy proxy = new LandlordProxy(landlord); ?? // 從中介進(jìn)行租房 ?? ? ? ?proxy.apartmentToRent(); ?? ?} }

得出最終結(jié)果:

json復(fù)制代碼出租房前,收取中介費(fèi) 杭州房東出租房子 出租房后,簽訂合同

通過上述 demo 我們大概了解代理模式是怎么一回事

  • 優(yōu)點:

    • 在不修改目標(biāo)對象的功能前提下,能通過代理對象對目標(biāo)功能擴(kuò)展

  • 缺點:

    • 代理對象需要與目標(biāo)對象實現(xiàn)一樣的接口,所以會有很多代理類,一旦接口增加方法,目標(biāo)對象與代理對象都要維護(hù)

四、動態(tài)代理

動態(tài)代理利用了JDK API,動態(tài)地在內(nèi)存中構(gòu)建代理對象,從而實現(xiàn)對目標(biāo)對象的代理功能,動態(tài)代理又被稱為JDK代理或接口代理。

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

  • 靜態(tài)代理在編譯時就已經(jīng)實現(xiàn)了,編譯完成后代理類是一個實際的 class 文件

  • 動態(tài)代理是在運(yùn)行時動態(tài)生成的,即編譯完成后沒有實際的 class 文件,而是在運(yùn)行時動態(tài)生成類字節(jié)碼,并加載到 JVM

1、JDK代理

代碼如下:

java復(fù)制代碼public class ProxyFactory { ?? ?// 目標(biāo)方法 ?? ?public Object target; ?? ?public ProxyFactory(Object target) { ?? ? ? ?this.target = target; ?? ?} ? ? ?public Object getProxyInstance() { ?? ? ? ?return Proxy.newProxyInstance( ?? ? ? ? ? ? ? ?// 目標(biāo)對象的類加載器 ?? ? ? ? ? ? ? ?target.getClass().getClassLoader(), ?? ? ? ? ? ? ? ?// 目標(biāo)對象的接口類型 ?? ? ? ? ? ? ? ?target.getClass().getInterfaces(), ?? ? ? ? ? ? ? ?// 事件處理器 ?? ? ? ? ? ? ? ?new InvocationHandler() { ?? ? ? ? ? ? ? ? ? ?/** ?? ? ? ? ? ? ? ? ? ? * ?? ? ? ? ? ? ? ? ? ? * @param proxy ?代理對象 ?? ? ? ? ? ? ? ? ? ? * @param method 代理對象調(diào)用的方法 ?? ? ? ? ? ? ? ? ? ? * @param args ? 代理對象調(diào)用方法時實際的參數(shù) ?? ? ? ? ? ? ? ? ? ? * @return ?? ? ? ? ? ? ? ? ? ? * @throws Throwable ?? ? ? ? ? ? ? ? ? ? */ ?? ? ? ? ? ? ? ? ? ?@Override ?? ? ? ? ? ? ? ? ? ?public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ?? ? ? ? ? ? ? ? ? ? ? ?System.out.println("我是前置增強(qiáng)"); ?? ? ? ? ? ? ? ? ? ? ? ?method.invoke(target, args); ?? ? ? ? ? ? ? ? ? ? ? ?System.out.println("我是后置增強(qiáng)"); ?? ? ? ? ? ? ? ? ? ? ? ?return null; ?? ? ? ? ? ? ? ? ? ?} ?? ? ? ? ? ? ? ?} ?? ? ? ?); ?? ?} }

我們測試一下:

java復(fù)制代碼public class JavaMain { ?? ?public static void main(String[] args) { ?? ? ? ?Landlord landlord = new HangZhouLandlord(); ? ? ? ? ?System.out.println(landlord.getClass()); ? ? ? ? ?Landlord proxy = (Landlord) new ProxyFactory(landlord).getProxyInstance(); ? ? ? ? ?proxy.apartmentToRent(); ? ? ? ? ?System.out.println(proxy.getClass()); ? ?? ? ? ?while (true){} ?? ?} }

得出結(jié)果:

json復(fù)制代碼class com.company.proxy.HangZhouLandlord 我是前置增強(qiáng) 杭州房東出租房子 我是后置增強(qiáng) class com.sun.proxy.$Proxy0

這里可能有小伙伴已經(jīng)懵了,接著往后看

1.1 JDK類的動態(tài)生成

Java虛擬機(jī)類加載過程主要分為五個階段:加載、驗證、準(zhǔn)備、解析、初始化。其中加載階段需要完成以下3件事情:

  1. 通過一個類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流

  2. 將這個字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時數(shù)據(jù)結(jié)構(gòu)

  3. 在內(nèi)存中生成一個代表這個類的 java.lang.Class 對象,作為方法區(qū)這個類的各種數(shù)據(jù)訪問入口

由于虛擬機(jī)規(guī)范對這3點要求并不具體,所以實際的實現(xiàn)是非常靈活的,關(guān)于第1點,獲取類的二進(jìn)制字節(jié)流(class字節(jié)碼)就有很多途徑:

  • 從本地獲取

  • 從網(wǎng)絡(luò)中獲取

  • 運(yùn)行時計算生成,這種場景使用最多的是動態(tài)代理技術(shù),在 java.lang.reflect.Proxy 類中,就是用了 ProxyGenerator.generateProxyClass 來為特定接口生成形式為 *$Proxy 的代理類的二進(jìn)制字節(jié)流

  • 所以,動態(tài)代理就是想辦法,根據(jù)接口或目標(biāo)對象,計算出代理類的字節(jié)碼,然后再加載到 JVM 中使用

1.2 JDK動態(tài)代理流程

所以,我們可以得出一個結(jié)論:我們上面的 $Proxy0 實際上是 JVM 在編譯時期加載出來的類,由于這個類是編譯時期加載的,所以我們沒辦法在 IDEA 里面看到。

可能一般的文章,到這里基本就結(jié)束了,讓大家知道 $Proxy0是由 JVM 編譯時期加載出來的類

但大家都知道,小黃的文章主打的就是一個硬核、源碼級。所以,我們直接去看 $Proxy0 的源代碼

首先,我們需要下載一個 arthas 的產(chǎn)品,網(wǎng)址:arthas.aliyun.com/doc/,跟隨流程解壓…

Arthas 是一款線上監(jiān)控診斷產(chǎn)品,通過全局視角實時查看應(yīng)用 load、內(nèi)存、gc、線程的狀態(tài)信息,并能在不修改應(yīng)用代碼的情況下,對業(yè)務(wù)問題進(jìn)行診斷,包括查看方法調(diào)用的出入?yún)?、異常,監(jiān)測方法執(zhí)行耗時,類加載信息等,大大提升線上問題排查效率。

當(dāng)我們一切準(zhǔn)備完成后,啟動我們上面動態(tài)代理的測試 JavaMain

啟動完成后,進(jìn)入我們的 arthas 頁面,執(zhí)行命令:java -jar arthas-boot.jar

我們可以看到,我們的目標(biāo)類 com.company.proxy.JavaMain 就出現(xiàn)了,隨后我們按下 4,進(jìn)入到我們的監(jiān)控頁面。

隨后使用 jad com.sun.proxy.$Proxy0 之后,可以看到我們已經(jīng)解析出來 $Proxy0 的源碼了

我們將其復(fù)制到下面,并刪減一些不必要的信息。

java復(fù)制代碼public final class $Proxy0 extends Proxy implements Landlord { ?? ?private static Method m3; ? ?? ?// $Proxy0 類的構(gòu)造方法 ?? ?// 參數(shù)為 invocationHandler ?? ?public $Proxy0(InvocationHandler invocationHandler) { ?? ? ? ?super(invocationHandler); ?? ?} ? ? ?static { ?? ? ? ?m3 = Class.forName("com.company.proxy.Landlord").getMethod("apartmentToRent", new Class[0]); ?? ?} ? ? ?public final void apartmentToRent() { ?? ? ? ?this.h.invoke(this, m3, null); ?? ? ? ?return; ?? ?} }

我們先看其有參構(gòu)造方法,可以看到 $Proxy0 的構(gòu)造方法入?yún)?InvocationHandler,有沒有感覺似曾相識。

如果你這里忘掉了,不妨去看一下動態(tài)代理的 ProxyFactory 的代碼,可以發(fā)現(xiàn),我們 Proxy.newProxyInstance() 的第三個自定義的參數(shù),也正是我們的 InvocationHandler

我們猜測一下,如果這里的傳的 InvocationHandler 是我們之前自定義的 InvocationHandler

那么,如果我調(diào)用 $Proxy0.apartmentToRent() 是不是就是執(zhí)行下面的代碼:

java復(fù)制代碼public final void apartmentToRent() { ?? ?this.h.invoke(this, m3, null); ?? ?return; } ?// 這里的h.invoke執(zhí)行的是我們這里自定義的方法,然后進(jìn)行的前后增強(qiáng) public Object getProxyInstance() { ?? ? ? ?return Proxy.newProxyInstance( ?? ? ? ? ? ? ? ?target.getClass().getClassLoader(), ?? ? ? ? ? ? ? ?target.getClass().getInterfaces(), ?? ? ? ? ? ? ? ?new InvocationHandler() { ?? ? ? ? ? ? ? ? ? ?@Override ?? ? ? ? ? ? ? ? ? ?public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ?? ? ? ? ? ? ? ? ? ? ? ?System.out.println("我是前置增強(qiáng)"); ?? ? ? ? ? ? ? ? ? ? ? ?method.invoke(target, args); ?? ? ? ? ? ? ? ? ? ? ? ?System.out.println("我是后置增強(qiáng)"); ?? ? ? ? ? ? ? ? ? ? ? ?return null; ?? ? ? ? ? ? ? ? ? ?} ?? ? ? ? ? ? ? ?} ?? ? ? ?);

如果說我們這個猜測是正確的話,那么會得出這樣的幾個結(jié)論:

  • 我們的代理類實際上是實現(xiàn)了 Landlord 的接口,然后重寫了 Landlord 接口中的 apartmentToRent 方法

  • 當(dāng)外界調(diào)用代理類的 apartmentToRent() 方法時,實際上是調(diào)用的我們自定義的 new InvocationHandler() 類里面的 invoke 方法

還有我們的最后一步,也就是證明 $Proxy0 的構(gòu)造入?yún)?InvocationHandler 就是我們自定義的 InvocationHandler,廢話不多說,直接來看代理的源碼。

java復(fù)制代碼return Proxy.newProxyInstance(ClassLoader,Interfaces,new InvocationHandler() {}); public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h){ ?? ?// cl = class com.sun.proxy.$Proxy0 ?? ?Class<?> cl = getProxyClass0(loader, intfs); ?? ?// cons = public com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler) ?? ?final Constructor<?> cons = cl.getConstructor(constructorParams); ?? ?// 根據(jù)構(gòu)造參數(shù)實例化對象 ?? ?return cons.newInstance(new Object[]{h}); }

我們通過源碼可以看到,一共分為三步(下面為反射的內(nèi)容,如不熟悉可提前學(xué)習(xí)下反射):

  • 拿到 $Proxy0Class

  • 根據(jù) Class 拿到其構(gòu)造方法

  • 根據(jù)構(gòu)造方法傳入?yún)?shù)進(jìn)行實例化

這就確定了我們上述的猜想是正確的。

2、Cglib代理

cglib (Code Generation Library ) 是一個第三方代碼生成類庫,運(yùn)行時在內(nèi)存中動態(tài)生成一個子類對象從而實現(xiàn)對目標(biāo)對象功能的擴(kuò)展。cglib 為沒有實現(xiàn)接口的類提供代理,為 JDK 的動態(tài)代理提供了很好的補(bǔ)充。

  • 最底層是字節(jié)碼

  • ASM 是操作字節(jié)碼的工具

  • cglib 基于 ASM 字節(jié)碼工具操作字節(jié)碼(即動態(tài)生成代理,對方法進(jìn)行增強(qiáng))

  • SpringAOP 基于 cglib 進(jìn)行封裝,實現(xiàn) cglib 方式的動態(tài)代理

使用 cglib 需要引入 cglib 的jar包,如果你已經(jīng)有 spring-core 的jar包,則無需引入,因為 spring 中包含了cglib 。

  • cglib 的Maven坐標(biāo)

    xml復(fù)制代碼<dependency> ?? ?<groupId>cglib</groupId> ?? ?<artifactId>cglib</artifactId> ?? ?<version>3.2.5</version> </dependency>


2.1 cglib動態(tài)代理實現(xiàn)

還是同樣的配方,我們要創(chuàng)建一個需要代理的類(UserServiceImpl),但不需要實現(xiàn)任何的接口,因為我們的 cglib 是根據(jù)類來進(jìn)行創(chuàng)建的。

UserServiceImpl

java復(fù)制代碼public class UserServiceImpl { ?? ?// 查詢功能 ?? ?List<String> findUserList() { ?? ? ? ?return Collections.singletonList("小A"); ?? ?} }

實現(xiàn) cglib 的工廠類:UserLogProxy

java復(fù)制代碼public class UserLogProxy implements MethodInterceptor { ?? ?/** ?? ? * 生成 CGLIB 動態(tài)代理類方法 ?? ? * ?? ? * @param target ?? ? * @return ?? ? */ ?? ?public Object getLogProxy(Object target) { ?? ? ? ?// 增強(qiáng)器類,用來創(chuàng)建動態(tài)代理類 ?? ? ? ?Enhancer enhancer = new Enhancer(); ? ? ? ? ?// 設(shè)置代理類的父類字節(jié)碼對象 ?? ? ? ?enhancer.setSuperclass(target.getClass()); ? ? ? ? ?// 設(shè)置回調(diào) ?? ? ? ?enhancer.setCallback(this); ? ? ? ? ?// 創(chuàng)建動態(tài)代理對象并返回 ?? ? ? ?return enhancer.create(); ? ? ?} ? ? ?/** ?? ? * @param o ? ? ? ? 代理對象 ?? ? * @param method ? ? ?目標(biāo)對象中的方法的Method實例 ?? ? * @param objects ? ? 實際參數(shù) ?? ? * @param methodProxy ? 代理類對象中的方法的Method實例 ?? ? * @return ?? ? * @throws Throwable ?? ? */ ?? ?@Override ?? ?public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { ?? ? ? ?System.out.println("前置輸出"); ?? ? ? ?Object result = methodProxy.invokeSuper(o, objects); ?? ? ? ?return result; ?? ?} }

測試程序:JavaMainTest

java復(fù)制代碼public class JavaMainTest { ?? ?public static void main(String[] args) { ? ? ? ? ?// 目標(biāo)對象 ?? ? ? ?UserServiceImpl userService = new UserServiceImpl(); ?? ? ? ?System.out.println(userService.getClass()); ? ? ? ? ?// 代理對象 ?? ? ? ?UserServiceImpl proxy = (UserServiceImpl) new UserLogProxy().getLogProxy(userService); ?? ? ? ?System.out.println(proxy.getClass()); ? ? ? ? ?List<String> list = proxy.findUserList(); ?? ? ? ?System.out.println("用戶信息:" + list); ? ? ? ? ?while (true) { ? ? ? ? ?} ?? ?} }

結(jié)果:

java復(fù)制代碼class com.study.spring.proxy.UserServiceImpl class com.study.spring.proxy.UserServiceImpl$$EnhancerByCGLIB$$cd9788d 前置輸出 用戶信息:[小A]

2.2 cglib代理流程

按照上述我們分析 $Proxy0 的方法,將 com.study.spring.proxy.UserServiceImpl$$EnhancerByCGLIB$$cd9788d 取出,得到如下:

java復(fù)制代碼public class UserServiceImpl$$EnhancerByCGLIB$$cd9788d extends UserServiceImpl implements Factory { ?? ?final List findUserList() { ?? ? ? ?// 是否設(shè)置了回調(diào) ?? ? ? ?MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0; ?? ? ? ?if (methodInterceptor == null) { ?? ? ? ? ? ?UserServiceImpl$$EnhancerByCGLIB$$cd9788d.CGLIB$BIND_CALLBACKS(this); ?? ? ? ? ? ?methodInterceptor = this.CGLIB$CALLBACK_0; ?? ? ? ?} ?? ? ? ?// 設(shè)置回調(diào),需要調(diào)用 intercept 方法 ?? ? ? ?if (methodInterceptor != null) { ?? ? ? ? ? ?return (List) methodInterceptor.intercept(this, CGLIB$findUserList$0$Method, CGLIB$emptyArgs, CGLIB$findUserList$0$Proxy); ?? ? ? ?} ?? ? ? ?// 無回調(diào),調(diào)用父類的 findUserList 即可 ?? ? ? ?return super.findUserList(); ?? ?} ?? ?final List CGLIB$findUserList$0() { ?? ? ? ?return super.findUserList(); ?? ?} }

博主先把整個流程圖放到下面,然后結(jié)合流程圖來進(jìn)行講解:

  • JVM 編譯期間,我們的 Enhancer 會根據(jù)目標(biāo)類的信息去動態(tài)的生成 動態(tài)代理類并設(shè)置 回調(diào)

  • 當(dāng)用戶在通過上述的動態(tài)代理類執(zhí)行 findUserList() 方法時,有兩個執(zhí)行選項

    • 若設(shè)置了回調(diào)接口,則直接調(diào)用UserLogProxy 中的 intercept ,然后通過 FastClass 類調(diào)用動態(tài)代理類,執(zhí)行CGLIB$findUserList$0 方法,調(diào)用父類的 findUserList() 方法

    • 若沒有設(shè)置回調(diào)接口,則直接調(diào)用父類的 findUserList() 方法

五、代理模式總結(jié)

1、三種代理模式實現(xiàn)方式的對比

  • jdk 代理和 CGLIB 代理

    • 使用 CGLib 實現(xiàn)動態(tài)代理,CGLib 底層采用 ASM 字節(jié)碼生成框架,使用字節(jié)碼技術(shù)生成代理類,在JDK1.6 之前比使用 Java 反射效率要高。唯一需要注意的是,CGLib 不能對聲明為 final 的類或者方法進(jìn)行代理,因為 CGLib 原理是動態(tài)生成被代理類的子類。

    • JDK1.6、JDK1.7、JDK1.8 逐步對 JDK 動態(tài)代理優(yōu)化之后,在調(diào)用次數(shù)較少的情況下,JDK 代理效率高于 CGLib 代理效率,只有當(dāng)進(jìn)行大量調(diào)用的時候,JDK1.6JDK1.7CGLib 代理效率低一點,但是到 JDK1.8 的時候,JDK 代理效率高于 CGLib 代理。所以如果有接口使用 JDK 動態(tài)代理,如果沒有接口使用 CGLIB 代理。

  • 動態(tài)代理和靜態(tài)代理

    • 動態(tài)代理與靜態(tài)代理相比較,最大的好處是接口中聲明的所有方法都被轉(zhuǎn)移到調(diào)用處理器一個集中的方法中處理(InvocationHandler.invoke)。這樣,在接口方法數(shù)量比較多的時候,我們可以進(jìn)行靈活處理,而不需要像靜態(tài)代理那樣每一個方法進(jìn)行中轉(zhuǎn)。

    • 如果接口增加一個方法,靜態(tài)代理模式除了所有實現(xiàn)類需要實現(xiàn)這個方法外,所有代理類也需要實現(xiàn)此方法。增加了代碼維護(hù)的復(fù)雜度。而動態(tài)代理不會出現(xiàn)該問題

2、代理模式優(yōu)缺點

優(yōu)點:

  • 代理模式在客戶端與目標(biāo)對象之間起到一個中介作用和保護(hù)目標(biāo)對象的作用;

  • 代理對象可以擴(kuò)展目標(biāo)對象的功能;

  • 代理模式能將客戶端與目標(biāo)對象分離,在一定程度上降低了系統(tǒng)的耦合度;

缺點:

  • 增加了系統(tǒng)的復(fù)雜度;

3、代理模式使用場景

  • 功能增強(qiáng)

    • 當(dāng)需要對一個對象的訪問提供一些額外操作時,可以使用代理模式

  • 遠(yuǎn)程(Remote)代理

    • 實際上,RPC 框架也可以看作一種代理模式,GoF 的《設(shè)計模式》一書中把它稱作遠(yuǎn)程代理。通過遠(yuǎn)程代理,將網(wǎng)絡(luò)通信、數(shù)據(jù)編解碼等細(xì)節(jié)隱藏起來??蛻舳嗽谑褂?RPC 服務(wù)的時候,就像使用本地函數(shù)一樣,無需了解跟服務(wù)器交互的細(xì)節(jié)。除此之外,RPC 服務(wù)的開發(fā)者也只需要開發(fā)業(yè)務(wù)邏輯,就像開發(fā)本地使用的函數(shù)一樣,不需要關(guān)注跟客戶端的交互細(xì)節(jié)。

  • 防火墻(Firewall)代理

    • 當(dāng)你將瀏覽器配置成使用代理功能時,防火墻就將你的瀏覽器的請求轉(zhuǎn)給互聯(lián)網(wǎng);當(dāng)互聯(lián)網(wǎng)返回響應(yīng)時,代理服務(wù)器再把它轉(zhuǎn)給你的瀏覽器。

  • 保護(hù)(Protect or Access)代理

    • 控制對一個對象的訪問,如果需要,可以給不同的用戶提供不同級別的使用權(quán)限。

六、結(jié)尾

終于寫完了這篇文章,動態(tài)代理在我看 AOP 源碼時,就感覺挺抽象的

我感覺最大的原因應(yīng)該在于:代理類動態(tài)生成,無法查看,導(dǎo)致對其模糊,從而陷入不理解

但通過這篇文章,我相信,99% 的人應(yīng)該都可以理解了動態(tài)代理模式的來龍去脈

當(dāng)然,好刀要用在刀刃上,在面試中,若面試官提及 設(shè)計模式動態(tài)代理Spring、Dubbo 都可以引出動態(tài)代理,基本這篇文章無差別秒殺

如果你能看到這,那博主必須要給你一個大大的鼓勵,謝謝你的支持!

喜歡的可以點個關(guān)注,后續(xù)會更新 Spring 源碼系列文章

我是愛敲代碼的小黃,獨角獸企業(yè)的Java開發(fā)工程師,CSDN博客專家,Java領(lǐng)域新星創(chuàng)作者,喜歡后端架構(gòu)和中間件源碼。

2023年再不會動態(tài)代理,就要被淘汰了的評論 (共 條)

分享到微博請遵守國家法律
应城市| 普安县| 万盛区| 石家庄市| 同德县| 砀山县| 泗水县| 普定县| 美姑县| 英德市| 孝昌县| 巨鹿县| 海宁市| 清河县| 宜兴市| 邮箱| 石楼县| 抚松县| 西丰县| 通州市| 江华| 阿拉善左旗| 西安市| 宝兴县| 巴马| 沁源县| 宝坻区| 芒康县| 治多县| 双江| 博乐市| 六枝特区| 义马市| 陇南市| 云安县| 鄂温| 武鸣县| 长垣县| 大荔县| 湄潭县| 博罗县|