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

老生常談設(shè)計(jì)模式之動(dòng)態(tài)代理

 更新時(shí)間:2017年06月12日 08:22:21   投稿:jingxian  
下面小編就為大家?guī)?lái)一篇老生常談設(shè)計(jì)模式之動(dòng)態(tài)代理。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

一、動(dòng)態(tài)代理概念

動(dòng)態(tài)代理分為JDK動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理兩種方式。

jdk動(dòng)態(tài)代理是由Java內(nèi)部的反射機(jī)制來(lái)實(shí)現(xiàn)的,cglib動(dòng)態(tài)代理底層則是借助asm來(lái)實(shí)現(xiàn)的。

總的來(lái)說(shuō),反射機(jī)制在生成類的過(guò)程中比較高效,而asm在生成類之后的相關(guān)執(zhí)行過(guò)程中比較高效(可以通過(guò)將asm生成的類進(jìn)行緩存,這樣解決asm生成類過(guò)程低效問題)。

還有一點(diǎn)必須注意:jdk動(dòng)態(tài)代理的應(yīng)用前提,必須是目標(biāo)類基于統(tǒng)一的接口。如果沒有上述前提,jdk動(dòng)態(tài)代理不能應(yīng)用。

由此可以看出,jdk動(dòng)態(tài)代理有一定的局限性,cglib這種第三方類庫(kù)實(shí)現(xiàn)的動(dòng)態(tài)代理應(yīng)用更加廣泛,且在效率上更有優(yōu)勢(shì)。

二、JDK動(dòng)態(tài)代理

以下代碼使用代理模式實(shí)現(xiàn)一個(gè)大小寫字符轉(zhuǎn)換的功能。

定義接口和實(shí)現(xiàn)類:

ISomeService接口:

package com.ietree.basicskill.designpattern.dynamicproxy.jdk;

/**
 * 接口類
 * 
 * @author Root
 */
public interface ISomeService {
  
  String doFirst();
  
  void doSecond();
}

SomeServiceImpl實(shí)現(xiàn)類:

package com.ietree.basicskill.designpattern.dynamicproxy.jdk;

/**
 * 實(shí)現(xiàn)類
 * 
 * @author Root
 */
public class SomeServiceImpl implements ISomeService {

  @Override
  public String doFirst() {
    System.out.println("執(zhí)行doFirst()...");
    String result = "abcde";
    return result;
  }

  @Override
  public void doSecond() {
    System.out.println("執(zhí)行doSecond()...");
  }

}

JDK動(dòng)態(tài)代理類:

package com.ietree.basicskill.designpattern.dynamicproxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Main {
  public static void main(String[] args) {

    final ISomeService target = new SomeServiceImpl();
    
    // 使用JDK的Proxy動(dòng)態(tài)代理,要求目標(biāo)類和代理類必須實(shí)現(xiàn)相同的接口,因?yàn)槠涞讓拥膱?zhí)行原理與靜態(tài)代理的相同
    ISomeService service = (ISomeService) Proxy.newProxyInstance(
        // 目標(biāo)類的類加載器
        target.getClass().getClassLoader(),
        // 目標(biāo)類所實(shí)現(xiàn)的所有接口
        target.getClass().getInterfaces(), 
        new InvocationHandler() {
          // proxy:代理對(duì)象
          // method:目標(biāo)方法
          // args:目標(biāo)方法的參數(shù)列表
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 調(diào)用目標(biāo)方法
            Object result = method.invoke(target, args);
            if (result != null) {
              result = ((String) result).toUpperCase();
            }
            return result;
          }
        });
    String result = service.doFirst();
    System.out.println(result);

    service.doSecond();
  }
}

三、cglib動(dòng)態(tài)代理

Cglib是一個(gè)優(yōu)秀的動(dòng)態(tài)代理框架,它的底層使用ASM在內(nèi)存中動(dòng)態(tài)的生成被代理類的子類,使用CGLIB即使代理類沒有實(shí)現(xiàn)任何接口也可以實(shí)現(xiàn)動(dòng)態(tài)代理功能。CGLIB具有簡(jiǎn)單易用,它的運(yùn)行速度要遠(yuǎn)遠(yuǎn)快于JDK的Proxy動(dòng)態(tài)代理:

CGLIB的核心類:

net.sf.cglib.proxy.Enhancer – 主要的增強(qiáng)類

net.sf.cglib.proxy.MethodInterceptor – 主要的方法攔截類,它是Callback接口的子接口,需要用戶實(shí)現(xiàn)

net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method類的代理類,可以方便的實(shí)現(xiàn)對(duì)源對(duì)象方法的調(diào)用,如使用:

Object o = methodProxy.invokeSuper(proxy, args);//雖然第一個(gè)參數(shù)是被代理對(duì)象,也不會(huì)出現(xiàn)死循環(huán)的問題。

net.sf.cglib.proxy.MethodInterceptor接口是最通用的回調(diào)(callback)類型,它經(jīng)常被基于代理的AOP用來(lái)實(shí)現(xiàn)攔截(intercept)方法的調(diào)用。這個(gè)接口只定義了一個(gè)方法

public Object intercept(Object object, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable;

第一個(gè)參數(shù)是代理對(duì)像,第二和第三個(gè)參數(shù)分別是攔截的方法和方法的參數(shù)。原來(lái)的方法可能通過(guò)使用java.lang.reflect.Method對(duì)象的一般反射調(diào)用,或者使用 net.sf.cglib.proxy.MethodProxy對(duì)象調(diào)用。net.sf.cglib.proxy.MethodProxy通常被首選使用,因?yàn)樗臁?/p>

以下程序?qū)崿F(xiàn)了大小寫轉(zhuǎn)換的功能:

實(shí)現(xiàn)類SomeService:

package com.ietree.basicskill.designpattern.dynamicproxy.cglib;

/**
 * 實(shí)現(xiàn)類
 * 
 * @author Root
 */
public class SomeService {

  public String doFirst() {
    System.out.println("執(zhí)行doFirst()...");
    String result = "abcde";
    return result;
  }

  public void doSecond() {
    System.out.println("執(zhí)行doSecond()...");
  }

}

代理類MyCglibFactory:

package com.ietree.basicskill.designpattern.dynamicproxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MyCglibFactory implements MethodInterceptor {

  private SomeService target;
  
  public MyCglibFactory() {
    super();
    target = new SomeService();
  }

  public SomeService myCglibCreator() {
    // 創(chuàng)建增強(qiáng)器對(duì)象
    Enhancer enhancer = new Enhancer();
    // 指定目標(biāo)類,即父類
    enhancer.setSuperclass(SomeService.class);
    // 設(shè)置回調(diào)接口對(duì)象
    enhancer.setCallback(this);

    return (SomeService) enhancer.create();
  }

  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    // 調(diào)用目標(biāo)方法
    Object result = method.invoke(target, args);
    if (result != null) {
      result = ((String) result).toUpperCase();
    }
    return result;
  }

}

測(cè)試:

package com.ietree.basicskill.designpattern.dynamicproxy.cglib;

public class Main {
  public static void main(String[] args) {

    SomeService service = new MyCglibFactory().myCglibCreator();
    
    String result = service.doFirst();
    System.out.println("result = " + result);

    service.doSecond();
  }
}

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

執(zhí)行doFirst()...
result = ABCDE
執(zhí)行doSecond()...

以上這篇老生常談設(shè)計(jì)模式之動(dòng)態(tài)代理就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • feign GET請(qǐng)求不支持對(duì)象傳參的坑及解決

    feign GET請(qǐng)求不支持對(duì)象傳參的坑及解決

    這篇文章主要介紹了feign GET請(qǐng)求不支持對(duì)象傳參的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 使用SpringMVC 重寫、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù)

    使用SpringMVC 重寫、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù)

    這篇文章主要介紹了使用SpringMVC 重寫、擴(kuò)展HttpServletRequest請(qǐng)求參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 詳解Java設(shè)計(jì)模式之外觀模式

    詳解Java設(shè)計(jì)模式之外觀模式

    在Java開發(fā)中,設(shè)計(jì)模式是一種十分常見的編程思想,它可以幫助我們解決很多實(shí)際開發(fā)中的問題,本篇文章將介紹一種常見的設(shè)計(jì)模式——外觀模式,并結(jié)合實(shí)際的開發(fā)場(chǎng)景進(jìn)行講解,需要的朋友可以參考下
    2023-06-06
  • java日期格式化YYYY-MM-dd遇坑指南小結(jié)

    java日期格式化YYYY-MM-dd遇坑指南小結(jié)

    本文主要介紹了java日期格式化YYYY-MM-dd遇坑指南小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Java HttpClient用法的示例詳解

    Java HttpClient用法的示例詳解

    Java開發(fā)語(yǔ)言中實(shí)現(xiàn)HTTP請(qǐng)求的方法主要有兩種:一種是JAVA的標(biāo)準(zhǔn)類HttpUrlConnection;另一種是第三方開源框架HTTPClient。本文就將詳細(xì)講講Java中HttpClient的使用,需要的可以參考一下
    2022-07-07
  • Java中的關(guān)鍵字volatile詳解

    Java中的關(guān)鍵字volatile詳解

    這篇文章主要介紹了Java中的關(guān)鍵字volatile,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 在SpringBoot項(xiàng)目中獲取Request的四種方法

    在SpringBoot項(xiàng)目中獲取Request的四種方法

    這篇文章主要為大家詳細(xì)介紹了SpringBoot項(xiàng)目中獲取Request的四種方法,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-11-11
  • Kotlin 和 Java 混合開發(fā)入門教程

    Kotlin 和 Java 混合開發(fā)入門教程

    這篇文章主要介紹了入門 Kotlin 和 Java 混合開發(fā),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • java高并發(fā)ScheduledThreadPoolExecutor類深度解析

    java高并發(fā)ScheduledThreadPoolExecutor類深度解析

    這篇文章主要為大家介紹了java高并發(fā)ScheduledThreadPoolExecutor類源碼深度解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Java實(shí)現(xiàn)常用加密算法——單向加密算法MD5和SHA

    Java實(shí)現(xiàn)常用加密算法——單向加密算法MD5和SHA

    本篇文章主要介紹了Java實(shí)現(xiàn)常用加密算法——單向加密算法MD5和SHA,信息加密后數(shù)據(jù)更安全,需要的朋友可以參考下。
    2016-10-10

最新評(píng)論

双桥区| 青岛市| 元阳县| 古交市| 和平县| 洛扎县| 东兴市| 宜良县| 龙山县| 德保县| 新建县| 含山县| 喀喇沁旗| 松滋市| 葫芦岛市| 中西区| 枝江市| 赞皇县| 蒲江县| 唐河县| 博爱县| 阿勒泰市| 南充市| 渝中区| 洪泽县| 柳州市| 南漳县| 隆化县| 楚雄市| 辉南县| 临夏县| 岳阳县| 汉阴县| 南汇区| 桃源县| 达州市| 西吉县| 秭归县| 墨脱县| 澎湖县| 塘沽区|