欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解析動態(tài)代理jdk的Proxy與spring的CGlib(包括區(qū)別介紹)

 更新時間:2022年01月22日 11:58:06   作者:三只蛋黃派  
Spring是Java程序員基本不可能繞開的一個框架,它的核心思想是IoC(控制反轉(zhuǎn))和AOP(面向切面編程)。本文重點給大家介紹動態(tài)代理jdk的Proxy與spring的CGlib,感興趣的朋友跟隨小編一起看看吧

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

動態(tài)代理:在不改變原有代碼的情況下上進(jìn)行對象功能增強 使用代理對象代替原來的對象完成功能 進(jìn)而達(dá)到拓展功能的目的

2.JDK Proxy 動態(tài)代理面向接口的動態(tài)代理

特點:

  • 一定要有接口和實現(xiàn)類的存在 代理對象增強的是實現(xiàn)類 在實現(xiàn)接口的方法重寫的方法
  • 生成的代理對象只能轉(zhuǎn)換成 接口的不能轉(zhuǎn)換成 被代理類
  • 代理對象只能增強接口中定義的方法 實現(xiàn)類中其他和接口無關(guān)的方法是無法增強的
  • 代理對象只能讀取到接口中方法上的注解 不能讀取到實現(xiàn)類方法上的注解
  • 使用方法:
public class Test1 {
    public static void main(String[] args) {
        Dinner dinner=new Person("張三");
        // 通過Porxy動態(tài)代理獲得一個代理對象,在代理對象中,對某個方法進(jìn)行增強
//        ClassLoader loader,被代理的對象的類加載器
        ClassLoader classLoader = dinner.getClass().getClassLoader();
//        Class<?>[] interfaces,被代理對象所實現(xiàn)的所有接口
        Class[] interaces= dinner.getClass().getInterfaces();
//        InvocationHandler h,執(zhí)行處理器對象,專門用于定義增強的規(guī)則
        InvocationHandler handler = new InvocationHandler(){
            // invoke 當(dāng)我們讓代理對象調(diào)用任何方法時,都會觸發(fā)invoke方法的執(zhí)行
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                Object proxy, 代理對象
//                Method method,被代理的方法
//                Object[] args,被代理方法運行時的實參
                Object res=null;
               if(method.getName().equals("eat")){
                   System.out.println("飯前洗手");
                   // 讓原有的eat的方法去運行
                   res =method.invoke(dinner, args);
                   System.out.println("飯后刷碗");
               }else{
                   // 如果是其他方法,那么正常執(zhí)行就可以了
                   res =method.invoke(dinner, args);
               }
                return res;
            }
        };
        Dinner dinnerProxy =(Dinner) Proxy.newProxyInstance(classLoader,interaces,handler);
        //dinnerProxy.eat("包子");
        dinnerProxy.drink();
    }
}
interface Dinner{
    void eat(String foodName);
    void drink();
}
class Person implements Dinner{
    private String name;
    public Person(String name) {
        this.name = name;
    }
    @Override
    public void eat(String foodName) {
        System.out.println(name+"正在吃"+foodName);
    }
    @Override
    public void drink( ) {
        System.out.println(name+"正在喝茶");
    }
}
class Student implements Dinner{
    private String name;
    public Student(String name) {
        this.name = name;
    }
    @Override
    public void eat(String foodName) {
        System.out.println(name+"正在食堂吃"+foodName);
    }
    @Override
    public void drink( ) {
        System.out.println(name+"正在喝可樂");
    }
}

3.CGlib動態(tài)代理

cglib動態(tài)代理模式是面向父類

特點:

面向父類的和接口沒有直接關(guān)系
2.不僅可以增強接口中定義的方法還可以增強其他方法
3.可以讀取父類中方法上的所有注解

使用實例

public class Test1 {
    @Test
    public void testCglib(){
        Person person =new Person();
        // 獲取一個Person的代理對象
        // 1 獲得一個Enhancer對象
        Enhancer enhancer=new Enhancer();
        // 2 設(shè)置父類字節(jié)碼
        enhancer.setSuperclass(person.getClass());
        // 3 獲取MethodIntercepter對象 用于定義增強規(guī)則
        MethodInterceptor methodInterceptor=new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                /*Object o,  生成之后的代理對象 personProxy
                Method method,  父類中原本要執(zhí)行的方法  Person>>> eat()
                Object[] objects, 方法在調(diào)用時傳入的實參數(shù)組
                MethodProxy methodProxy  子類中重寫父類的方法 personProxy >>> eat()
                */
                Object res =null;
                if(method.getName().equals("eat")){
                    // 如果是eat方法 則增強并運行
                    System.out.println("飯前洗手");
                    res=methodProxy.invokeSuper(o,objects);
                    System.out.println("飯后刷碗");
                }else{
                    // 如果是其他方法 不增強運行
                    res=methodProxy.invokeSuper(o,objects); // 子類對象方法在執(zhí)行,默認(rèn)會調(diào)用父類對應(yīng)被重寫的方法
                }
                return res;
            }
        };
        // 4 設(shè)置methodInterceptor
        enhancer.setCallback(methodInterceptor);
        // 5 獲得代理對象
        Person personProxy = (Person)enhancer.create();
        // 6 使用代理對象完成功能
        personProxy.eat("包子");
    }
}
class Person  {
    public Person( ) {
    }
    public void eat(String foodName) {
        System.out.println("張三正在吃"+foodName);
    }
}

原理區(qū)別:

java動態(tài)代理是利用反射機制生成一個實現(xiàn)代理接口的匿名類,在調(diào)用具體方法前調(diào)用InvokeHandler來處理。

而cglib動態(tài)代理是利用asm開源包,對代理對象類的class文件加載進(jìn)來,通過修改其字節(jié)碼生成子類來處理。

1、如果目標(biāo)對象實現(xiàn)了接口,默認(rèn)情況下會采用JDK的動態(tài)代理實現(xiàn)AOP 
2、如果目標(biāo)對象實現(xiàn)了接口,可以強制使用CGLIB實現(xiàn)AOP 

3、如果目標(biāo)對象沒有實現(xiàn)了接口,必須采用CGLIB庫,spring會自動在JDK動態(tài)代理和CGLIB之間轉(zhuǎn)換

如何強制使用CGLIB實現(xiàn)AOP?
 (1)添加CGLIB庫,SPRING_HOME/cglib/*.jar
 (2)在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>

JDK動態(tài)代理和CGLIB字節(jié)碼生成的區(qū)別?
 (1)JDK動態(tài)代理只能對實現(xiàn)了接口的類生成代理,而不能針對類
 (2)CGLIB是針對類實現(xiàn)代理,主要是對指定的類生成一個子類,覆蓋其中的方法
   因為是繼承,所以該類或方法最好不要聲明成final 

兩個動態(tài)代理的區(qū)別

  • JDK動態(tài)代理是面向接口的,只能增強實現(xiàn)類中接口中存在的方法。CGlib是面向父類的,可以增強父類的所有方法
  • JDK得到的對象是JDK代理對象實例,而CGlib得到的對象是被代理對象的子類 生活雖然苦悶,但跑起來總是帶風(fēng)!

到此這篇關(guān)于解析動態(tài)代理jdk的Proxy與spring的CGlib的文章就介紹到這了,更多相關(guān)動態(tài)代理jdk的Proxy與spring的CGlib內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • OpenStack?安裝?Keystone的過程詳解

    OpenStack?安裝?Keystone的過程詳解

    這篇文章主要介紹了OpenStack?安裝?Keystone,本篇主要記錄一下?openstack?queens?版本?keystone?組件的安裝過程,本文通過圖文實例相結(jié)合給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-05-05
  • Sublime?Text?4怎么安裝使用

    Sublime?Text?4怎么安裝使用

    這篇文章主要介紹了Sublime?Text?4怎么安裝使用,下載對應(yīng)的安裝包,將該exe文件復(fù)制到對應(yīng)的sublime?text的安裝目錄下(與sublime_text.exe同級),右鍵管理員運行即可,需要的朋友跟隨小編一起看看吧
    2022-01-01
  • HTTP協(xié)議簡介_動力節(jié)點Java學(xué)院整理

    HTTP協(xié)議簡介_動力節(jié)點Java學(xué)院整理

    這篇文章主要介紹了HTTP協(xié)議簡介,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • gb2312的詳細(xì)介紹

    gb2312的詳細(xì)介紹

    gb2312的詳細(xì)介紹,需要的朋友可以參考一下
    2013-03-03
  • 用戶權(quán)限管理設(shè)計[圖文說明]

    用戶權(quán)限管理設(shè)計[圖文說明]

    用戶管理權(quán)限設(shè)計一直是大家討論的熱點,因為幾乎涉及到每一個開發(fā)的業(yè)務(wù)系統(tǒng)。我找了很多很多的資料,大家的核心基本上都是一樣的:基于角色管理. 用戶,角色,模塊,權(quán)限的相互組合,就可以形成一個強大的權(quán)限管理系統(tǒng)。
    2008-12-12
  • VS2019如何查看類圖的方法實現(xiàn)

    VS2019如何查看類圖的方法實現(xiàn)

    這篇文章主要介紹了VS2019如何查看類圖的方法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • VS2019 安裝時閃退的解決方法

    VS2019 安裝時閃退的解決方法

    這篇文章主要介紹了VS2019 安裝時閃退的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • vscode入門教程之頁面啟動與代碼調(diào)試

    vscode入門教程之頁面啟動與代碼調(diào)試

    VScode是微軟推出的一款輕量級的編輯器,采用了和VS相同的UI界面。今天小編給大家?guī)硪黄绾问褂胿scode來進(jìn)行最基本的工作的小教程,希望大家能夠喜歡
    2020-01-01
  • wap開發(fā)中如何有效的利用緩存減少消息的傳送量

    wap開發(fā)中如何有效的利用緩存減少消息的傳送量

    由于WAP信道帶寬的限制,我們在編寫WAP應(yīng)用的時候都希望最大限度地減少消息的傳送量。
    2010-06-06
  • 如何使用git拉取gitlab上的項目

    如何使用git拉取gitlab上的項目

    這篇文章主要介紹了如何使用git拉取gitlab上的項目問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11

最新評論