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

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

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

1.動態(tài)代理


1.1什么是動態(tài)代理?

動態(tài)代理(理解) 基于反射機制

舉個例子,生活中一般在打官司的時候都會請代理律師,為什么要請律師呢?是因為開庭的時候大部人對于打官司沒有經(jīng)驗,只會說出自己案件的陳述,并不會根據(jù)法律等爭取自己權益的最大化,此時就可以請律師幫助自己不僅完成對案件的陳述,還能爭取權益最大化。那么Java中也是一樣,如果要對功能進行增強就可以使用動態(tài)代理。

我們知道Spring是通過JDK或者CGLib實現(xiàn)動態(tài)代理的,今天我們討論一下JDK實現(xiàn)動態(tài)代理的原理。

1.2動態(tài)代理的實現(xiàn)方式有幾種?

  1. JDK動態(tài)代理
  2. CGLB動態(tài)代理

1.3動態(tài)代理的概念和優(yōu)點

相比于靜態(tài)代理(在靜態(tài)代理中,對于類的每一個接口,我們都要單獨寫一個代理類),動態(tài)代理在創(chuàng)建代理對象上更加的靈活。

有需求,有問題,才會有解決方法和改進創(chuàng)新。那么產(chǎn)生動態(tài)代理的問題根源或者需求是什么呢?在靜態(tài)代理中,由于每個接口都需要我們單獨的寫一個代理類,比較麻煩,因此我們就想,我們能不能寫一個類,我們只需要把委托對象(目標對象),還有全部接口(共同行為,其實委托對象中就已經(jīng)包含接口了)作為參數(shù)傳給這個類的方法,然后這個方法就可以給我們返回一個我們想要的代理對象呢,并且這個代理對象可以給我們代理全部的共同行為,像是租房,結婚等?

  • 動態(tài)代理類的字節(jié)碼在程序運行時由JAVA反射機制動態(tài)產(chǎn)生。會根據(jù)需要,通過反射機制,在程序運行期動態(tài)的為目標對象(委托對象)創(chuàng)建代理對象,無需程序員手動編寫代理對象所屬類的代碼。
  • 動態(tài)代理不僅簡化了編程工作,而且提高了軟件系統(tǒng)的可擴展性,因為反射機制的使用使得可以生成任意類型的代理對象。
  • 動態(tài)代理的實現(xiàn)方式有兩種,分別是:JDK動態(tài)代理和CGLIB動態(tài)代理。
  • 動態(tài)代理的目標對象是不固定的(也就是說把任何一個目標對象或者說是委托對象作為參數(shù)傳遞給生成代理對象的對象的方法,都會給我們返回一個我們想要的代理對象);使用動態(tài)代理以后,會在應用程序執(zhí)行的時候,動態(tài)的創(chuàng)建目標對象代理對象依然會增強目標對象的行為;

2.JDK動態(tài)代理的概念和特點

先說一個需要注意的點:JDK動態(tài)代理的目標對象必須要有接口實現(xiàn),也就是說:委托類必須要繼承接口。

在JDK中,有一個Proxy類(名詞,代理人)。Proxy類是專門完成代理的操作類,可以通過此類為一個或多個接口動態(tài)的生成實現(xiàn)類(對這個類的其他方法我了解的也不是很多,我們可以看JDK的在線API文檔,百度搜一下好像挺多的)。這個類提供的有一個靜態(tài)方法:newProxyInstance()方法。這個方法的目的就是給我們的目標對象(委托對象)返回一個代理對象。

newProxyInstance()方法需要有三個參數(shù):

  1. 類加載器(ClassLoader對象)
  2. 接口集合(一個Interface對象的數(shù)組,就是需要代理對象代理那些共同行為,也是委托對象繼承的共同行為接口)
  3. 一個InvocationHandler接口對象(當然可以是它的一個實現(xiàn)類對象)。這個接口中有一個invoke()方法。invoke()方法起到的作用很大,當代理對象調用共同行為方法的時候,invoke()方法就會被自動調用執(zhí)行。

下面粘貼一張圖片:

jdk動態(tài)代理,java,開發(fā)語言

2.1動態(tài)代理的介紹

jdk動態(tài)代理,java,開發(fā)語言

  1. ?動態(tài)代理是指代理類對象在程序運行時由JVM根據(jù)反射機制動態(tài)生成的。動態(tài)代理不需要定義代理類的,java源文件。
  2. 動態(tài)代理其實就是jdk運行期間,動態(tài)創(chuàng)建class字節(jié)碼并加載到JVM。
  3. 動態(tài)代理的實現(xiàn)方式常用的有兩種:使用JDK代理,與通過CGLlB動態(tài)代理。

2.2動態(tài)代理的實現(xiàn)

  1. jdk動態(tài)代理(理解):使用java反射包中的類和接口實現(xiàn)動態(tài)代理的功能,反射包java.lang.reflect,里面有三個類:InvocationHandler,Method,Proxy
  2. cglib動態(tài)代理(了解): cglib是第三方的工具庫,創(chuàng)建代理對象
  • cglib的原理是繼承,cglib通過繼承目標類,創(chuàng)建它的子類,在子類中
    重寫父類中同名的方法,實現(xiàn)功能的修改。
  • 因為cglib是繼承,重寫方法,所以要求目標類不能是fina1的,方法也不能是final的。cglib的要求目標類比較寬松,只要能繼承就可以了。cglib在很多的框架中使用,
    比如mybatis,spring框架中都有使用

jdk動態(tài)代理,java,開發(fā)語言

2.3CGLB動態(tài)代理

CGLB動態(tài)代理即Code Generation Library,是一個開源的第三方工具庫,其原理是繼承,去生成目標類的子類對象,這樣對子類的功能進行增強。但是要求:目標類不能用final修飾,目標類中的方法也不能被final修飾。

2.4動態(tài)代理的效率

CGLB動態(tài)代理的效率要大于JDK動態(tài)代理的效率。

3.為什么使用JDK動態(tài)代理?

3.1代碼案例:

  1. 請看如下例子,一個音樂人的本質會唱歌、會跳舞、會rap等,但是觀眾進入演唱會所時首先要交門票,最基本的實現(xiàn)方法是直接對方法進行改造,添加對應的功能。
    package com.zhao.service.impl;
    
    import com.zhao.service.Actor;
    
    public class CXK implements Actor {
    
    
        @Override
        public void sing(int money) {
    
            System.out.println("聽"+money);
        }
    
        @Override
        public String dance() {
            System.out.println("吹灰舞");
    
            return "發(fā)放簽名";
        }
    
        @Override
        public void rap() {
    
            System.out.println("練習時長兩年");
        }
    }
    
  2. 這樣操作發(fā)現(xiàn)出現(xiàn)了大量重復的代碼,如果有十處、一百處需要同樣的處理那么代碼需要重復十次、一百次。當然我們可以把這些功能封裝成一個增強方法,然后在功能方法中進行調用,但是也出現(xiàn)了方法的十處、一百處的調用操作,一旦增強方法名字改變,就需要完成所有調用處代碼的修改?;蛘哂幸惶觳恍枰@些增強操作了,就再次需要在這十處、一百處刪除方法調用。所以這種操作不適用于大型的項目開發(fā)的需求,此時我們就必須使用Java的動態(tài)代理機制。

在Java開發(fā)中如果一個類中的方法在基本功能之外需要進行功能擴充或者功能增強,如:事務控制、權限判斷、日志記錄等等操作,此時可以使用動態(tài)代理機制。

Java的JDK中Proxy類可以實現(xiàn)基于接口的動態(tài)代理,實現(xiàn)步驟示例如下:

  1. 因為Proxy類必須基于接口進行動態(tài)代理,所以首先創(chuàng)建接口,定義接口的規(guī)范,即功能方法的定義。
    package com.zhao.service;
    /**
     * 演員接口
     * 
     */
    public interface Actor {
       //唱歌
        void sing(int money);
        //跳舞
        String dance();
        //rap
        void rap();
    }
    
  2. 定義實現(xiàn)接口的子類,實現(xiàn)接口定義的方法,此方法只需要把核心功能實現(xiàn)即可,其他增強的操作可以在代理類中實現(xiàn)。
    package com.zhao.service.impl;
    
    import com.zhao.service.Actor;
    
    public class CXK implements Actor {
    
    
        @Override
        public void sing(int money) {
    
            System.out.println("聽"+money);
        }
    
        @Override
        public String dance() {
            System.out.println("吹灰舞");
    
            return "發(fā)放簽名";
        }
    
        @Override
        public void rap() {
    
            System.out.println("練習時長兩年");
        }
    }
    
  3. 定義代理類,在代理類中對被代理對象進行方法增強。
    package com.zhao.advice;
    
    import com.zhao.service.Actor;
    import com.zhao.service.impl.CXK;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class JJGS {
        public static void main(String[] args) {
            //1.創(chuàng)建被代理類的對象----具體的人物cxk
            Actor cxk=new CXK();
            //2.創(chuàng)建代理對象--- 具體某人為上面cxk
            /**
             * ClassLoader loader:類的加載器---聯(lián)系方式
             * Class<?>[] interfaces:類的接口類型---被代理人的類型
             * InvocationHandleer h:處理---我要幫你干什么
             */
            Actor jjr=(Actor) Proxy.newProxyInstance(CXK.class.getClassLoader(), CXK.class.getInterfaces(), new InvocationHandler() {
                /**
                 *
                 *  Object proxy:被代理對象的引用,系統(tǒng)會自動創(chuàng)建被代理對象的一個映射
                 * Method method:被代理對象的方法
                 * @param args
                 *Object[] args:被代理對象方法的參數(shù)
                 * 返回值是被代理對象執(zhí)行后的返回值
                 */
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //被代理對象方法的執(zhí)行,并獲得返回值
                    Object result=null;
                    result=method.invoke(cxk,args);
    
                    System.out.println("演出后的增強:結算費用并納稅");
                    return result;
                }
            });
    
            //3.執(zhí)行功能
    //        jjr.sing(5000);
            String dance = jjr.dance();
            System.out.println(dance);
    
        }
    }
    

? 測試結果:

jdk動態(tài)代理,java,開發(fā)語言文章來源地址http://www.zghlxwxcb.cn/news/detail-698510.html

3.2基于子類的CGLib動態(tài)代理,可以使用Enhancer類完成直接對某個類進行動態(tài)代理。具體操作步驟如下:

  1. 創(chuàng)建被代理的類,并且定義功能方法,只需要完成核心功能即可。
    package com.zhao.service.impl;
    
    public class Actor {
        public void sing(int money) {
    
            System.out.println("聽" + money);
        }
    
        public String dance(int money) {
            System.out.println("吹灰舞"+money);
    
            return "發(fā)放簽名";
        }
    
        public void rap(int money) {
    
            System.out.println("練習時長兩年"+money);
        }
    }
    
  2. 定義代理類,使用Enhancer創(chuàng)建代理對象,對被代理對象進行方法增強。
    package com.zhao.advice;
    import com.zhao.service.impl.Actor;
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class JJGss {
        public static void main(String[] args) {
            //1.被代理的對象
            Actor actor=new Actor();
            //2.使用CGLIb的Enhancer類創(chuàng)建代理對象
            Actor proxyActor = (Actor) Enhancer.create(Actor.class, new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    String methodName=method.getName();
                    String money=args[0];
                    Object result=null;
                    if(methodName.equals("danceAct")){
                        System.out.println("對方法執(zhí)行前進性代理增強...");
                        result=method.invoke(actor,money);
                        System.out.println("對方法執(zhí)行后進性代理增強...");
    
                        return result;
                    }
                    return result;
                }
            });
    
            //
            proxyActor.dance(3000);
        }
    }
    

到了這里,關于Java——JDK動態(tài)代理的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領支付寶紅包贊助服務器費用

相關文章

  • java中的靜態(tài)代理、jdk動態(tài)代理以及CGLIB 動態(tài)代理

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

    2024年02月11日
    瀏覽(26)
  • [Java]靜態(tài)代理、動態(tài)代理(基于JDK1.8)

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

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

    2024年03月09日
    瀏覽(27)
  • 代理模式 靜態(tài)代理和動態(tài)代理(jdk、cglib)——Java入職第十一天

    代理模式 靜態(tài)代理和動態(tài)代理(jdk、cglib)——Java入職第十一天

    ? ? ? ? 一個類代表另一個類去完成擴展功能,在主體類的基礎上,新增一個代理類,擴展主體類功能,不影響主體,完成額外功能。比如買車票,可以去代理點買,不用去火車站,主要包括靜態(tài)代理和動態(tài)代理兩種模式。 代理類中包含了主體類 無法根據(jù)業(yè)務擴展,每一次

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

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

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

    2024年03月14日
    瀏覽(28)
  • JDK動態(tài)代理和CGLIB動態(tài)代理

    JDK動態(tài)代理和CGLIB動態(tài)代理 ① JDK動態(tài)代理只提供接口的代理,不支持類的代理,要求被代理類實現(xiàn)接口。JDK動態(tài)代理的核心是InvocationHandler接口和Proxy類,在獲取代理對象時,使用Proxy類來動態(tài)創(chuàng)建目標類的代理類(即最終真正的代理類,這個類繼承自Proxy并實現(xiàn)了我們定義的

    2024年02月07日
    瀏覽(16)
  • 【動態(tài)代理】JDK動態(tài)代理與cglib動態(tài)代理源碼解析

    【動態(tài)代理】JDK動態(tài)代理與cglib動態(tài)代理源碼解析

    UserService ,接口類 UserServiceImpl ,實現(xiàn)類 使用代理,測試效果。 控制臺輸出: Proxy#newProxyInstance ,生成代理類的實例。 核心在于 getProxyClass0 ,生成代理類的類信息 使用自定義的InvocationHandler作為參數(shù),調用構造函數(shù)獲取代理類對象實例 WeakCache#get ProxyClassFactory#apply ,實現(xiàn)了

    2024年02月04日
    瀏覽(21)
  • cglib動態(tài)代理、jdk動態(tài)代理及spring動態(tài)代理使用

    cglib動態(tài)代理、jdk動態(tài)代理及spring動態(tài)代理使用

    NickelBeforeAdvice.java方法執(zhí)行之前 NickelAfterReturningAdvice.java方法執(zhí)行之后 NickelAroundadvice.java環(huán)繞方法 NickelThrowAdvice.java拋異常方法 UserService.java拋異常方法 SpringProxtFactoryTest.java測試方法 NickelStaticMethodMatherPointcut.java方法匹配的方法 NickelPointcutAdvisor.java切面方法 SpringProxtFactoryTest.j

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

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

    代理模式是一種比較好理解的設計模式。簡單來說就是 我們使用代理對象來代替對真實對象(real object)的訪問,這樣就可以在不修改原目標對象的前提下,提供額外的功能操作,擴展目標對象的功能。 代理模式的主要作用是擴展目標對象的功能,比如說在目標對象的某個方法

    2024年02月13日
    瀏覽(25)
  • 通俗易懂 快速理解 JDK動態(tài)代理 和 cglib動態(tài)代理

    通俗易懂 快速理解 JDK動態(tài)代理 和 cglib動態(tài)代理

    動態(tài)代理的實現(xiàn)方案有兩種, JDK動態(tài)代理 和 CGLIB動態(tài)代理 ,區(qū)別在于JDK自帶的動態(tài)代理,必須要有接口,而CGLIB動態(tài)代理有沒有接口都可以。 JDK動態(tài)代理 :JDK原生的實現(xiàn)方式,需要被代理的目標類必須實現(xiàn)接口。因為這個技術要求 代理對象和目標對象實現(xiàn)同樣的接口 (兄

    2024年02月08日
    瀏覽(23)
  • 【spring】jdk動態(tài)代理和cglib動態(tài)代理的區(qū)別

    一、說明 1.spring aop中的動態(tài)代理主要有兩種方式,jdk動態(tài)代理和cglib動態(tài)代理 2.從實現(xiàn)接口、繼承父類的角度討論區(qū)別 3.從限制角度討論區(qū)別 4.從性能上討論區(qū)別 二、區(qū)別 1.jdk動態(tài)代理只提供接口類的代理,如果目標類不是接口,只能用cglib代理 2.jdk動態(tài)代理會在運行時為目

    2024年02月16日
    瀏覽(19)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包