最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring學(xué)習(xí)之動態(tài)代理(JDK動態(tài)代理和CGLIB動態(tài)代理)

 更新時間:2017年07月14日 09:56:04   作者:顏洛濱  
本篇文章主要介紹了Spring學(xué)習(xí)之動態(tài)代理(JDK動態(tài)代理和CGLIB動態(tài)代理),具有一定的參考價值,感興趣的小伙伴們可以參考一下

前言

動態(tài)代理,是一種通過運行時操作字節(jié)碼,以達(dá)到增強類的功能的技術(shù),也是Spring AOP操作的基礎(chǔ),關(guān)于AOP的內(nèi)容,將在后面的筆記中詳細(xì)講解,本小節(jié)主要是理清楚動態(tài)代理,畢竟,Spring的AOP是基于動態(tài)代理技術(shù),對動態(tài)代理技術(shù)有所了解,對于學(xué)習(xí)Spring AOP也會有幫助

動態(tài)代理技術(shù)詳解

動態(tài)代理,現(xiàn)在主要是用于增強類的功能,同時由于是具有動態(tài)性,所以避免了需要頻繁創(chuàng)建類的操作,同時,也使得原有的代碼在不需要改變的情況下,對類的功能進(jìn)行增強,主要的動態(tài)代理技術(shù)有:通過實現(xiàn)目標(biāo)接口,重寫其方法,以增強其能力,典型的以JDK動態(tài)代理為代表;或者,通過繼承類,重寫其方法以增強其能力,典型的以CGLib為代表,這兩種技術(shù)分別從不同的方向來對類的能力進(jìn)行擴(kuò)充,接下來來具體看下這兩種技術(shù)的特點以及差異。

基于JDK動態(tài)代理

基于JDK的動態(tài)代理技術(shù),其主要特點就是目標(biāo)類,也就是需要被代理的類,必須有接口,并且代理類必須實現(xiàn)跟它一樣的接口,從而來起到代理其事務(wù)的功能,具體使用如下代碼所示,假設(shè)有一個UserService類,主要用于負(fù)責(zé)用戶的登錄和退出,同時,有個日志類,負(fù)責(zé)記錄用戶的操作信息,直接將信息日志寫在對應(yīng)的UserService實現(xiàn)類中,可以達(dá)到目的,但顯然這種方式不是很合理,特別是在UserService有很多個方法需要做日志記錄的時候,就會使得日志記錄代碼遍布整個UserService,不僅使得代碼的冗余很大,而且當(dāng)需要進(jìn)行修改的時候,也需要逐個修改,非常麻煩,這個時候,采用動態(tài)代理技術(shù)就是一種非常好的方法了。

/**
 * UserService接口
 */
interface UserService{

  void login();
  void logout();
}

/**
 * UseService實現(xiàn)類
 */
class UserServiceImpl implements UserService{

  @Override
  public void login() {
    System.out.println("someone login....");
  }

  @Override
  public void logout() {
    System.out.println("someone logout....");
  }
}


/**
 * 實現(xiàn)InvocationHandle接口,用于織入所要增強的代碼
 */
class UserServiceHandle implements InvocationHandler{

  private UserService userService;

  public UserServiceHandle(UserService userService) {
    this.userService = userService;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    LogService.info();
    Object object = method.invoke(userService, args);
    LogService.info();
    return object;
  }
}

/**
 * 代理類工廠,用于產(chǎn)生UseService類的代理類
 */
class ProxyFactory{

  public static UserService getProxyObject(UserService userService){

    // 使用JDK動態(tài)代理技術(shù)來創(chuàng)建對應(yīng)的代理類
    return (UserService) Proxy.newProxyInstance(
        userService.getClass().getClassLoader(),
        userService.getClass().getInterfaces(),
        new UserServiceHandle(userService)
    );
  }
}

這樣,當(dāng)我們需要使用UseService類的時候,只需要從ProxyFactory中獲取即可,而且獲取的對象是UserService對象的代理類,也就是說,獲得的對象是UserService對象的增強版

基于CGLib的動態(tài)代理技術(shù)

從上面的ProxyFactory工廠中可以看到,在使用JDK進(jìn)行創(chuàng)建動態(tài)代理對象的時候,需要為其提供接口,或者說,如果所要增強的目標(biāo)類沒有實現(xiàn)任何接口,則JDK動態(tài)代理技術(shù)是無法為其創(chuàng)建對應(yīng)的代理對象的,這是JDK動態(tài)代理技術(shù)的一種缺點,而CGLib動態(tài)代理技術(shù)則恰好彌補了這個缺點,CGLib動態(tài)代理技術(shù)使用的是繼承該類的方式,從而避免了需要接口的缺陷,具體使用如下所示,注意,需要導(dǎo)入對應(yīng)的依賴文件

/**
 * 基于CGLib的動態(tài)代理技術(shù)
 * 注意這里需要實現(xiàn)MethodInterceptor接口
 */
class ProxyFactory implements MethodInterceptor{

  // 提供對應(yīng)的增強操作類
  private Enhancer enhancer = new Enhancer();

  public UserService getProxyObject(Class clazz){
    // 設(shè)置所要增強的類的父類
    enhancer.setSuperclass(clazz);
    // 設(shè)置回調(diào)對象
    enhancer.setCallback(this);
    // 創(chuàng)建對應(yīng)的對象
    return (UserService) enhancer.create();
  }

  // 實現(xiàn)攔截方法,用于攔截對應(yīng)的方法,并且對對應(yīng)的方法進(jìn)行增強
  // 參數(shù)含義:傳入的對象, Method對象,方法的參數(shù),進(jìn)行代理后的Method對象
  @Override
  public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

    LogService.info();
    // 這里需要注意,由于methodProxy對象是增強后的Method對象,所以這里需要調(diào)用的
    // 是methodProxy父類的方法,也就是所以增強的類的方法,以實現(xiàn)原來的功能
    Object object = methodProxy.invokeSuper(o, objects);
    LogService.info();
    return object;
  }
}

可以看到,使用CGLib動態(tài)代理技術(shù)可以在不需要實現(xiàn)接口的情況下東塔為對象創(chuàng)建代理對象,在很大程度上彌補了JDK動態(tài)代理技術(shù)的缺點,不過由于CGLib動態(tài)代理技術(shù)是采用繼承目標(biāo)類的方式,所以也存在一些問題,比如說,對于final以及private修飾的方法是無法為其增強的,這里還需要注意一下。

總結(jié)

動態(tài)代理技術(shù)是實現(xiàn)AOP技術(shù)的基礎(chǔ),也是一種很方便地實現(xiàn)方式,常用的動態(tài)代理技術(shù)有基于JDK動態(tài)代理技術(shù)以及基于CGLib的動態(tài)代理技術(shù),兩種技術(shù)各有千秋,也都各有缺點基于JDK的動態(tài)代理技術(shù)需要為其提供接口,基于CGLib的動態(tài)代理技術(shù)不能為final以及private修飾的方法進(jìn)行增強,在使用的時候需要根據(jù)具體進(jìn)行進(jìn)行合理選擇。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JavaWeb動態(tài)導(dǎo)出Excel可彈出下載

    JavaWeb動態(tài)導(dǎo)出Excel可彈出下載

    這篇文章主要介紹了JavaWeb動態(tài)導(dǎo)出Excel,對Excel可彈出進(jìn)行下載操作,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Java使用DateTimeFormatter實現(xiàn)格式化時間

    Java使用DateTimeFormatter實現(xiàn)格式化時間

    這篇文章主要介紹了Java使用DateTimeFormatter實現(xiàn)格式化時間,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • SpringBoot項目中application.yml和bootstrap.yml文件的區(qū)別及說明

    SpringBoot項目中application.yml和bootstrap.yml文件的區(qū)別及說明

    `application.yml`和`bootstrap.yml`都是Spring Boot項目中的配置文件,但它們在加載時機、用途、優(yōu)先級、配置來源、適用場景和是否必須存在等方面存在區(qū)別
    2025-03-03
  • SpringBoot零基礎(chǔ)入門之基本操作與概念

    SpringBoot零基礎(chǔ)入門之基本操作與概念

    這篇文章主要介紹了SpringBoot的概念、創(chuàng)建和運行,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • SpringBoot統(tǒng)一返回格式的方法詳解

    SpringBoot統(tǒng)一返回格式的方法詳解

    今天小編主要是和大家分享一個讓代碼變得更簡潔的小技巧:統(tǒng)一返回格式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-08-08
  • JavaWeb學(xué)習(xí)筆記分享(必看篇)

    JavaWeb學(xué)習(xí)筆記分享(必看篇)

    下面小編就為大家?guī)硪黄狫avaWeb學(xué)習(xí)筆記分享(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • 詳解mybatis中association和collection的column傳入多個參數(shù)問題

    詳解mybatis中association和collection的column傳入多個參數(shù)問題

    這篇文章主要介紹了詳解mybatis中association和collection的column傳入多個參數(shù)問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • java中Class.forName的作用淺談

    java中Class.forName的作用淺談

    這篇文章介紹了java中Class.forName的作用,有需要的朋友可以參考一下
    2013-11-11
  • Java依賴包漏洞檢測命令詳解

    Java依賴包漏洞檢測命令詳解

    這篇文章主要介紹了Java依賴包漏洞檢測命令,你可以在修復(fù)漏洞后快速進(jìn)行依賴項的安全檢查,并生成新的報告,而不需要等待 CVE 數(shù)據(jù)庫的下載和更新,這樣可以顯著提高掃描的效率,需要的朋友可以參考下
    2024-11-11
  • springboot整合JPA過程解析

    springboot整合JPA過程解析

    這篇文章主要介紹了springboot整合JPA過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02

最新評論

弥勒县| 麻阳| 吴忠市| 谢通门县| 左贡县| 兴业县| 苍南县| 永善县| 枣庄市| 马龙县| 聂拉木县| 甘肃省| 清水河县| 华宁县| 丹巴县| 永济市| 高要市| 乌什县| 阳高县| 广德县| 奉新县| 南阳市| 社旗县| 内乡县| 静安区| 浦江县| 天长市| 海安县| 新源县| 始兴县| 永丰县| 体育| 开远市| 余姚市| 津南区| 乃东县| 瑞安市| 汤原县| 嘉兴市| 新宁县| 阆中市|