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

【Java】JDK動態(tài)代理實(shí)現(xiàn)原理

這篇具有很好參考價(jià)值的文章主要介紹了【Java】JDK動態(tài)代理實(shí)現(xiàn)原理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

代理模式
代理模式一般包含三個(gè)角色:

  1. Subject:主題對象,一般是一個(gè)接口,定義一些業(yè)務(wù)相關(guān)的基本方法。
  2. RealSubject:具體的主題對象實(shí)現(xiàn)類,它會實(shí)現(xiàn)Subject接口中的方法。
  3. Proxy:代理對象,里面包含一個(gè)RealSubject的引用,外部會通過這個(gè)代理對象,來實(shí)現(xiàn)RealSubject中方法的調(diào)用。

JAVA中提供了動態(tài)代理的實(shí)現(xiàn),需要依賴InvocationHandler。

舉個(gè)例子

Subject

首先創(chuàng)建一個(gè)主題對象,里面定義一個(gè)execute方法:

public interface Subject {
    void execute();
}

RealSubject

接著創(chuàng)建具體的主題對象實(shí)現(xiàn)類,它會實(shí)現(xiàn)Subject的方法

public class RealSubject implements Subject {
    @Override
    public void execute() {
        System.out.println("realsubject方法執(zhí)行");
    }
}

創(chuàng)建InvocationHandler

JDK動態(tài)代理需要依賴InvocationHandler,所以這里創(chuàng)建一個(gè)ProxyInvocationHandler實(shí)現(xiàn)它的invoke方法,并提供了getProxy方法來獲取創(chuàng)建的代理對象,ProxyInvocationHandler類中引用了需要代理的目標(biāo)對象,也就是RealSubject,在invoke方法中通過反射執(zhí)行了RealSubject中的方法:

public class ProxyInvocationHandler implements InvocationHandler {

    /**
     * 代理的目標(biāo)對象,也就是RealSubject
     */
    private Object target;

   /**
     * 構(gòu)造函數(shù)
     */
    public ProxyInvocationHandler(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("開始執(zhí)行方法:" + method.getName());
        // 通過反射執(zhí)行RealSubject中的方法
        Object result = method.invoke(target, args);
        System.out.println("結(jié)束執(zhí)行方法:" + method.getName());
        return null;
    }

    public Object getProxy() {
        // 創(chuàng)建代理對象,傳入了類加載器、要代理對象的接口、InvocationHandler(this當(dāng)前對象)
        return Proxy.newProxyInstance(Thread.currentThread()
                        .getContextClassLoader(), target.getClass().getInterfaces(), this);
    }
}

測試:

public class ProxyTest {
    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        // 創(chuàng)建實(shí)際的對象
        Subject subject = new RealSubject();
        // 創(chuàng)建InvocationHandler,這里傳入的真是對象
        ProxyInvocationHandler invocationHandler = new ProxyInvocationHandler(subject);
        // 獲取代理對象
        Subject proxy = (Subject) invocationHandler.getProxy();
        // 執(zhí)行方法
        proxy.execute();
    }
}

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

開始執(zhí)行方法:execute
realsubject方法執(zhí)行
結(jié)束執(zhí)行方法:execute

根據(jù)輸出結(jié)果,可以看出JDK動態(tài)代理,主要是通過InvocationHandler生成一個(gè)代理對象,通過這個(gè)代理對象可以執(zhí)行目標(biāo)方法,執(zhí)行之時(shí),首先會進(jìn)入到InvocationHandler中的invoke方法,在創(chuàng)建InvocationHandler時(shí)
傳入了實(shí)際的對象RealSubject,所以InvocationHandler中可以拿到真實(shí)對象,只需要在InvocationHandler中的invoke方法中通過反射執(zhí)行RealSubject中對應(yīng)的方法即可。
【Java】JDK動態(tài)代理實(shí)現(xiàn)原理

動態(tài)代理實(shí)現(xiàn)原理

在ProxyInvocationHandler中可以看到通過Proxy創(chuàng)建了一個(gè)代理對象,那么接下來就進(jìn)入到Proxy中,看一下是如何創(chuàng)建代理對象的:

        // 創(chuàng)建代理對象,傳入了類加載器、要代理對象的接口、InvocationHandler(this當(dāng)前對象)
        return Proxy.newProxyInstance(Thread.currentThread()
                        .getContextClassLoader(), target.getClass().getInterfaces(), this);

Proxy

在Proxy中newProxyInstance方法創(chuàng)建代理對象的時(shí)候,傳入了類加載器、需要代理的對象以及InvocationHandler:

  1. 根據(jù)類加載器和需要代理的對象接口信息生成代理對象的class;
  2. 根據(jù)生成的代理類的class信息,獲取類的構(gòu)造器;
  3. 通過構(gòu)造器創(chuàng)建代理對象,并將InvocationHandler傳入;
public class Proxy implements java.io.Serializable {
    // 創(chuàng)建代理對象
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h) throws IllegalArgumentException {
        Objects.requireNonNull(h);
        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }
        // 1. 根據(jù)類加載器和需要代理的對象接口信息生成代理對象的class
        Class<?> cl = getProxyClass0(loader, intfs);
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
            // 2. 獲取類構(gòu)造器
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            // InvocationHandler
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            // 3. 通過構(gòu)造器創(chuàng)建代理對象,并將InvocationHandler傳入
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
           //...
        }
    }
}
生成代理類的class

getProxyClass0中首先會進(jìn)行邊界檢查,然后根據(jù)類加載器和需要代理的對象接口信息從緩存中獲取生成的代理類的calss,具體的實(shí)現(xiàn)在WeakCache的get方法中:

   /**
     * 代理類的緩存
     */
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

    /**
     * 生成代理類的class
     */
    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        // 邊界檢查
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }
        // 從緩存proxyClassCache中獲取class
        return proxyClassCache.get(loader, interfaces);
    }

   
WeakCache

WeakCache的get方法中如果根據(jù)緩存key獲取對象為空,會創(chuàng)建一個(gè)Factory對象賦值給Supplier,F(xiàn)actory是WeakCache的一個(gè)內(nèi)部類,它實(shí)現(xiàn)了Supplier接口,然后調(diào)用Supplier的get方法來生成代理類的class,接下來進(jìn)入到Factory的get方法中:

final class WeakCache<K, P, V> {
    // 獲取class
    public V get(K key, P parameter) {
        Objects.requireNonNull(parameter);
        expungeStaleEntries();
        // 獲取緩存key
        Object cacheKey = CacheKey.valueOf(key, refQueue);
        // 根據(jù)key獲取對象
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        // 如果為空
        if (valuesMap == null) {
            // 創(chuàng)建一個(gè)ConcurrentMap
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }
        // 創(chuàng)建subKey
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;
        while (true) {
            if (supplier != null) {
                // 調(diào)用get方法獲取class
                V value = supplier.get();
                if (value != null) {
                    return value;
                }
            }
            // 如果為空,創(chuàng)建Factory
            if (factory == null) {
                factory = new Factory(key, parameter, subKey, valuesMap);
            }
            // 如果supplier為null
            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    // 將factory賦值給supplier
                    supplier = factory;
                }
            } else {
                if (valuesMap.replace(subKey, supplier, factory)) {
                    supplier = factory;
                } else {
                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }
}
Factory

Factory是WeakCache的一個(gè)內(nèi)部類,它實(shí)現(xiàn)了Supplier接口,在get方法中,又調(diào)用了valueFactory的apply方法創(chuàng)建class,valueFactory是WeakCache的一個(gè)成員變量,在WeakCache的構(gòu)造函數(shù)中可以看到傳入了valueFactory對象進(jìn)行初始化,那么接下來就需要回到Proxy類中,看一下如何實(shí)例化WeakCache的:

final class WeakCache<K, P, V> {
    
    private final BiFunction<K, P, V> valueFactory;
    
    public WeakCache(BiFunction<K, P, ?> subKeyFactory,
                     BiFunction<K, P, V> valueFactory) {
        this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
        // 初始化
        this.valueFactory = Objects.requireNonNull(valueFactory);
    }

    // Factory
    private final class Factory implements Supplier<V> {

        private final K key;
        private final P parameter;
        private final Object subKey;
        private final ConcurrentMap<Object, Supplier<V>> valuesMap;

        Factory(K key, P parameter, Object subKey,
                ConcurrentMap<Object, Supplier<V>> valuesMap) {
            this.key = key;
            this.parameter = parameter;
            this.subKey = subKey;
            this.valuesMap = valuesMap;
        }

        @Override
        public synchronized V get() { 
            // 
            Supplier<V> supplier = valuesMap.get(subKey);
            if (supplier != this) {
                return null;
            }
            
            V value = null;
            try {
                // 調(diào)用valueFactory的apply方法創(chuàng)建class
                value = Objects.requireNonNull(valueFactory.apply(key, parameter));
            } finally {
                if (value == null) { // remove us on failure
                    valuesMap.remove(subKey, this);
                }
            }
            
            ......
              
            return value;
        }
    }
}
ProxyClassFactory

Proxy中WeakCache初始化的時(shí)候使用的是ProxyClassFactory類型的factory:

public class Proxy implements java.io.Serializable {  
     /**
     * WeakCache初始化
     */
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
}

所以調(diào)用valueFactory的apply方法的時(shí)候會進(jìn)入到ProxyClassFactory的apply方法,在apply方法中會通過ProxyGenerator動態(tài)生成代理類并加載類,然后將實(shí)例化的代理類返回:

 private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {
        // 前綴
        private static final String proxyClassNamePrefix = "$Proxy";

        // next number to use for generation of unique proxy class names
        private static final AtomicLong nextUniqueNumber = new AtomicLong();

        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            ......

            long num = nextUniqueNumber.getAndIncrement();
            String proxyName = proxyPkg + proxyClassNamePrefix + num;

            /*
             * 生成代理類
             */
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                // 加載代理,并返回對象
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                
                throw new IllegalArgumentException(e.toString());
            }
        }
    }
ProxyGenerator

ProxyGenerator是Proxy的一個(gè)內(nèi)部類,用于動態(tài)生成class:

 private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> {  
      public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
        ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
        // 生成class
        final byte[] var4 = var3.generateClassFile();
        // 是否保存到文件,如果開啟了之后,運(yùn)行程序之后會在包下面生成class文件
        if(saveGeneratedFiles) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    try {
                        int var1 = var0.lastIndexOf(46);
                        Path var2;
                        if(var1 > 0) {
                            Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar), new String[0]);
                            Files.createDirectories(var3, new FileAttribute[0]);
                            var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                        } else {
                            var2 = Paths.get(var0 + ".class", new String[0]);
                        }

                        Files.write(var2, var4, new OpenOption[0]);
                        return null;
                    } catch (IOException var4x) {
                        throw new InternalError("I/O exception saving generated file: " + var4x);
                    }
                }
            });
        }
        return var4;
    }
}
代理類的生成

由于設(shè)置了sun.misc.ProxyGenerator.saveGeneratedFiles為true,所以可以在包下面看到生成的代理類$Proxy0:
【Java】JDK動態(tài)代理實(shí)現(xiàn)原理

  1. 它繼承了Proxy并實(shí)現(xiàn)了Subject,并且在構(gòu)造函數(shù)中需要傳入InvocationHandler對象;
  2. 當(dāng)執(zhí)行$Proxy0中的execute方法時(shí),實(shí)際上調(diào)用的是InvocationHandler的invoke方法;

package com.sun.proxy;

import com.example.demo.bean.Subject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

// 動態(tài)生成了一個(gè)$Proxy0類,它繼承了Proxy并實(shí)現(xiàn)了Subject
public final class $Proxy0 extends Proxy implements Subject {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;
    // 傳入InvocationHandler對象
    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})).booleanValue();
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    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);
        }
    }
    
    // Subject的execute方法
    public final void execute() throws  {
        try {
            // 調(diào)用了InvocationHandler的invoke方法
            super.h.invoke(this, m3, (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)).intValue();
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
            m3 = Class.forName("com.example.demo.bean.Subject").getMethod("execute", new Class[0]);
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

總結(jié)

JDK的動態(tài)代理實(shí)現(xiàn)原理是在運(yùn)行中動態(tài)生成代理類,這個(gè)代理類實(shí)現(xiàn)了Subject接口,在對代理類進(jìn)行實(shí)例化的時(shí)候,需要傳入InvocationHandler,當(dāng)調(diào)用代理類的方法時(shí),會執(zhí)行InvocationHandler的invoke方法,在invoke方法中再執(zhí)行真正的目標(biāo)方法,從而完成代理功能。

參考

【拉勾教育】Dubbo源碼解讀與實(shí)戰(zhàn)-代理模式與常見實(shí)現(xiàn)文章來源地址http://www.zghlxwxcb.cn/news/detail-710795.html

到了這里,關(guān)于【Java】JDK動態(tài)代理實(shí)現(xiàn)原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

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

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

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

    2024年02月11日
    瀏覽(30)
  • 3_代理模式(動態(tài)代理JDK原生和CGLib)

    1.概念 代理模式(Proxy Pattern )是指 為其他對象提供一種代理,以控制對這個(gè)對象的訪問 ,屬于結(jié)構(gòu)型模式。 在某些情況下,一個(gè)對象不適合或者不能直接引用另一個(gè)對象,而代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用。 使用代理模式主要有兩個(gè)目的: 一是保護(hù)目標(biāo)

    2024年01月17日
    瀏覽(21)
  • 【深度思考】聊聊JDK動態(tài)代理原理

    首先,定義一個(gè)接口: 然后,新增一個(gè)類并實(shí)現(xiàn)上面的接口: 假設(shè)現(xiàn)在有這么一個(gè)需求:在不改動以上類代碼的前提下,對該方法增加一些前置操作或者后置操作。 接下來就來講解下,如何使用 JDK動態(tài)代理 來實(shí)現(xiàn)這個(gè)需求。 首先,自定義一個(gè)調(diào)用處理器,實(shí)現(xiàn) java.lang.r

    2023年04月17日
    瀏覽(19)
  • 【面試精講】Java動態(tài)代理是如何實(shí)現(xiàn)的?JDK Proxy 和 CGLib 有什么區(qū)別?

    【面試精講】Java動態(tài)代理是如何實(shí)現(xiàn)的?JDK Proxy 和 CGLib 有什么區(qū)別?

    Java動態(tài)代理是如何實(shí)現(xiàn)的?JDK Proxy 和 CGLib 有什么區(qū)別? 一、Java動態(tài)代理的實(shí)現(xiàn) 1、使用JDK Proxy實(shí)現(xiàn)動態(tài)代理 2、使用CGLib實(shí)現(xiàn)動態(tài)代理 二、JDK Proxy 與 CGLib 的區(qū)別 三、Spring中的動態(tài)代理 四、?Lombok代理原理 總結(jié) 本文深入探討了Java動態(tài)代理的實(shí)現(xiàn)機(jī)制,分別介紹了使用JDK

    2024年03月14日
    瀏覽(28)
  • JDK 動態(tài)代理(Spring AOP 的原理)(面試重點(diǎn))

    JDK 動態(tài)代理(Spring AOP 的原理)(面試重點(diǎn))

    ????????也叫委托模式.定義:為其他對象提供?種代理以控制對這個(gè)對象的訪問.它的作?就是通過提供?個(gè)代理類,讓我們 在調(diào)??標(biāo)?法的時(shí)候,不再是直接對?標(biāo)?法進(jìn)?調(diào)?,?是通過代理類間接調(diào)?,在某些情況下,?個(gè)對象不適合或者不能直接引?另?個(gè)對象,?代

    2024年01月22日
    瀏覽(43)
  • java中的靜態(tài)代理、jdk動態(tài)代理以及CGLIB 動態(tài)代理

    代理模式是一種比較好理解的設(shè)計(jì)模式。簡單來說就是 我們使用代理對象來代替對真實(shí)對象(real object)的訪問,這樣就可以在不修改原目標(biāo)對象的前提下,提供額外的功能操作,擴(kuò)展目標(biāo)對象的功能 那以下文章主要談三種代理模式, 分別是靜態(tài)代理,jdk的動態(tài)代理,cglib的動

    2024年02月11日
    瀏覽(26)
  • Java——JDK動態(tài)代理

    Java——JDK動態(tài)代理

    動態(tài)代理(理解) 基于反射機(jī)制 舉個(gè)例子,生活中一般在打官司的時(shí)候都會請代理律師,為什么要請律師呢?是因?yàn)殚_庭的時(shí)候大部人對于打官司沒有經(jīng)驗(yàn),只會說出自己案件的陳述,并不會根據(jù)法律等爭取自己權(quán)益的最大化,此時(shí)就可以請律師幫助自己不僅完成對案件的陳述

    2024年02月09日
    瀏覽(24)
  • Java代理之jdk動態(tài)代理+應(yīng)用場景實(shí)戰(zhàn)

    Java代理之jdk動態(tài)代理+應(yīng)用場景實(shí)戰(zhàn)

    本文將先介紹jdk動態(tài)代理的基本用法,并對其原理和注意事項(xiàng)予以說明。之后將以兩個(gè)最常見的應(yīng)用場景為例,進(jìn)行代碼實(shí)操。這兩個(gè)應(yīng)用場景分別是 攔截器 和 聲明性接口 ,它們在許多開發(fā)框架中廣泛使用。比如在spring和mybatis中均使用了攔截器模式,在mybatis中還利用動態(tài)

    2023年04月10日
    瀏覽(24)
  • [Java]靜態(tài)代理、動態(tài)代理(基于JDK1.8)

    [Java]靜態(tài)代理、動態(tài)代理(基于JDK1.8)

    【版權(quán)聲明】未經(jīng)博主同意,謝絕轉(zhuǎn)載?。ㄕ堊鹬卦瓌?chuàng),博主保留追究權(quán)) https://www.cnblogs.com/cnb-yuchen/p/18002823 出自【進(jìn)步*于辰的博客】 參考筆記一,P83;筆記二,P75.4。 目錄 1、概述 2、靜態(tài)代理的兩種形式 2.1 面向接口 2.2 面向繼承 3、動態(tài)代理的兩種形式 3.1 JDK動態(tài)代理

    2024年03月09日
    瀏覽(27)
  • Spring學(xué)習(xí)(五):一篇講清楚動態(tài)代理(jdk和cglib)的使用、原理和源碼

    Spring學(xué)習(xí)(五):一篇講清楚動態(tài)代理(jdk和cglib)的使用、原理和源碼

    目錄 一、jdk動態(tài)代理的基本使用 二、cglib動態(tài)代理的基本使用 2.1 方法一:method.invoke() 方法反射調(diào)用 2.2 方法二(spring使用的這個(gè)方法):?methodProxy.invoke() 2.3 方法三:methodProxy.invokeSuper() 三、jdk實(shí)現(xiàn)代理的原理? 四、jdk實(shí)現(xiàn)代理的源碼 五、jdk對代理的優(yōu)化? 六、cglib實(shí)現(xiàn)動

    2023年04月14日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包