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

詳解JAVA設(shè)計(jì)模式之代理模式

 更新時(shí)間:2020年06月19日 11:14:36   作者:WK_BlogYard  
這篇文章主要介紹了JAVA設(shè)計(jì)模式之代理模式的的相關(guān)資料,文中代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

什么是設(shè)計(jì)模式(Design Pattern)?

  設(shè)計(jì)模式是一套被反復(fù)使用,多數(shù)人知曉的,經(jīng)過分類編目的,代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。

代理模式的定義?

  代理模式就是為其他對(duì)象提供一種代理,以控制對(duì)這個(gè)對(duì)象的訪問。

  代理對(duì)象起到中介作用,可去掉功能服務(wù)或增加額外的服務(wù)。

代理對(duì)象和目標(biāo)對(duì)象的關(guān)系?

  代理對(duì)象:增強(qiáng)后的對(duì)象

  目標(biāo)對(duì)象:被增強(qiáng)的對(duì)象

  他們不是絕對(duì)的,會(huì)根據(jù)情況發(fā)生變化。

代理模式的兩種實(shí)現(xiàn)方式?

  1.靜態(tài)代理:代理和被代理對(duì)象在代理之前是確定的,它們都實(shí)現(xiàn)相同的接口或者繼承相同的抽象類。

  2.動(dòng)態(tài)代理:JDK通過接口反射得到字節(jié)碼,然后把字節(jié)碼轉(zhuǎn)換成class(通過native方法)

靜態(tài)代理實(shí)現(xiàn)的兩種方式?

  使用繼承方式實(shí)現(xiàn)和使用聚合方式實(shí)現(xiàn)。

  繼承:代理對(duì)象繼承目標(biāo)對(duì)象,重寫需要增強(qiáng)的方法。缺點(diǎn):代理類過多,產(chǎn)生類爆炸。

  聚合:目標(biāo)對(duì)象和代理對(duì)象實(shí)現(xiàn)同一個(gè)接口,代理對(duì)象當(dāng)中要包含目標(biāo)對(duì)象。

動(dòng)態(tài)代理的實(shí)現(xiàn)方式?

  Java動(dòng)態(tài)代理類位于java.lang.reflect包下,一般主要涉及到以下兩個(gè)類:

    1.Interface InvocationHandler : 該接口中僅定義了一個(gè)方法,public Object invoke(Object obj,Method method,Object[] args),在實(shí)際使用時(shí),第一個(gè)參數(shù)obj一般是指代理類,method是被代理的方法,args是該方法的參數(shù)數(shù)組,這個(gè)抽象方法在代理類中動(dòng)態(tài)實(shí)現(xiàn)。

    2.Proxy 該類即為動(dòng)態(tài)代理類,static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h):返回代理類的一個(gè)實(shí)例,返回后的代理類可以當(dāng)做被代理類使用(可使用被代理類在接口中聲明過的方法)

    所謂的動(dòng)態(tài)代理是這樣一種class:它是在運(yùn)行時(shí)生成的class,該class需要實(shí)現(xiàn)一組interface,使用動(dòng)態(tài)代理類時(shí),必須實(shí)現(xiàn)InvocationHandler接口。

JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理的區(qū)別?

  1.JDK動(dòng)態(tài)代理只能代理實(shí)現(xiàn)了接口的類,沒有實(shí)現(xiàn)接口的類不能實(shí)現(xiàn)JDK的動(dòng)態(tài)代理。

  2.CGLIB動(dòng)態(tài)代理針對(duì)類來實(shí)現(xiàn)代理的,對(duì)指定目標(biāo)類產(chǎn)生一個(gè)子類,通過方法攔截技術(shù)攔截所有的父類方法的調(diào)用。

動(dòng)態(tài)代理實(shí)現(xiàn)的思路:

  1.聲明一段源碼(動(dòng)態(tài)產(chǎn)生代理)

  2.編譯源碼(JDK Compiler API ),產(chǎn)生新的類(代理類)

  3.將這個(gè)類load到內(nèi)存中,產(chǎn)生一個(gè)新的對(duì)象(代理對(duì)象)

  4.return 代理對(duì)象。

使用靜態(tài)代理的例子:

  1.首先創(chuàng)建業(yè)務(wù)邏輯接口

/**
 * 接口
 * @author Administrator
 *
 */
public interface Moveable {
  /**
   *
   * 接口中的方法
   * @Description: TODO
   * @returnType: void
   */
  void move();
}

  2.創(chuàng)建實(shí)現(xiàn)類,實(shí)現(xiàn)接口中的方法

/**
 * 實(shí)現(xiàn)類
 * @author Administrator
 *
 */
public class Car implements Moveable {

  @Override
  public void move() {
    //實(shí)現(xiàn)開車
    try {
      Thread.sleep(new Random().nextInt(1000));
      System.out.println("汽車行駛中...");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

}

  3.使用繼承方式實(shí)現(xiàn)對(duì)實(shí)現(xiàn)類的代理

/**
 * 使用繼承方式實(shí)現(xiàn)代理
 * @author Administrator
 *
 */
public class Car2 extends Car {

  /* (non-Javadoc)
   * @see com.wk.design.proxy.Car#move()
   * 直接調(diào)用父類的move方法,這樣就形成了一個(gè)Car2對(duì)Car的代理
   */
  @Override
  public void move() {
    long startTime = System.currentTimeMillis();
    System.out.println("汽車開始行駛...");
    //使用繼承的方式調(diào)用父類的move()方法
    super.move();
    long endTime = System.currentTimeMillis();
    System.out.println("汽車行駛結(jié)束... 汽車行駛時(shí)間:"+(endTime-startTime)+"毫秒。");
  }

}

  4.創(chuàng)建測(cè)試類

/**
 * 測(cè)試類
 * @author Administrator
 *
 */
public class Test {

  public static void main(String[] args) {
//    Car car = new Car();
//    car.move();

    //使用繼承方式實(shí)現(xiàn)代理
    Moveable car2 = new Car2();
    car2.move();

    //使用聚合方式實(shí)現(xiàn)代理
//    Car car = new Car();
//    Moveable car3 = new Car3(car);
//    car3.move();

  }
}

  5.使用聚合方式實(shí)現(xiàn)對(duì)實(shí)現(xiàn)類的代理

    日志代理類

/**
 *
 * 日志代理類
 * @author Administrator
 *
 */
public class CarLogProxy implements Moveable {

  /**
   * 使用接口聲明代理類
   */
  private Moveable m;
  /**
   * 通過構(gòu)造方法的參數(shù)傳入代理類
   * @param m
   */
  public CarLogProxy(Moveable m) {
    super();
    this.m = m;
  }

  @Override
  public void move() {
    System.out.println("日志開始");
    //調(diào)用代理類的方法
    m.move();
    System.out.println("日志結(jié)束");

  }

}

    時(shí)間代理類

/**
 * 時(shí)間代理類
 * @author Administrator
 *
 */
public class CarTimeProxy implements Moveable {

  /**
   * 使用接口聲明代理類
   */
  private Moveable m;
  /**
   * 通過構(gòu)造方法的參數(shù)傳入代理類
   * @param m
   */
  public CarTimeProxy(Moveable m) {
    super();
    this.m = m;
  }

  @Override
  public void move() {
    long startTime = System.currentTimeMillis();
    System.out.println("汽車開始行駛...");
    //調(diào)用代理類的方法
    m.move();
    long endTime = System.currentTimeMillis();
    System.out.println("汽車行駛結(jié)束... 汽車行駛時(shí)間:"+(endTime-startTime)+"毫秒。");
  }

}

  6.創(chuàng)建聚合方式測(cè)試類

/**
 * 聚合代理測(cè)試類
 * @author Administrator
 *
 */
public class TestJuHeProxy {
  public static void main(String[] args) {
    Car car = new Car();
    //先記錄日志,再記錄時(shí)間
//    CarTimeProxy ctp = new CarTimeProxy(car);
//    CarLogProxy clp = new CarLogProxy(ctp);
//    clp.move();

    //先記錄時(shí)間,再記錄日志
    CarLogProxy clp = new CarLogProxy(car);
    CarTimeProxy ctp = new CarTimeProxy(clp);
    ctp.move();
  }

}

使用JDK動(dòng)態(tài)代理實(shí)現(xiàn)的例子:

  1.創(chuàng)建一個(gè)實(shí)現(xiàn)接口InvocationHandler的類,它必須實(shí)現(xiàn)invoke()方法。

  2.創(chuàng)建被代理類及接口

  3.調(diào)用Proxy的靜態(tài)方法,創(chuàng)建一個(gè)代理類

  4.通過代理調(diào)用方法

/**
 * 使用jdk的動(dòng)態(tài)代理
 * @author Administrator
 *
 */
public class TimeHandler implements InvocationHandler {

  /**
   * 被代理對(duì)象
   */
  private Object target;

  public TimeHandler(Object target) {
    super();
    this.target = target;
  }

  /**
   * 參數(shù):
   * proxy : 被代理對(duì)象
   * method : 被代理對(duì)象的方法
   * args : 方法的參數(shù)
   * 返回值:
   * Object 方法的返回值
   */
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //在執(zhí)行被代理對(duì)象的方法之前執(zhí)行自己的邏輯
    long startTime = System.currentTimeMillis();
    System.out.println("汽車開始行駛...");
    //執(zhí)行被代理對(duì)象的方法
    method.invoke(target);
    //在執(zhí)行被代理對(duì)象的方法之后執(zhí)行自己的邏輯
    long endTime = System.currentTimeMillis();
    System.out.println("汽車行駛結(jié)束... 汽車行駛時(shí)間:"+(endTime-startTime)+"毫秒。");
    return null;
  }

}
 /**
  * JDK動(dòng)態(tài)代理測(cè)試類
  * @author Administrator
  *
  */
 public class JdkProxyTest {
 
   public static void main(String[] args) {
     Car car = new Car();
     InvocationHandler h = new TimeHandler(car);
     Class<?> cls = car.getClass();
     /**
     * 參數(shù):
     *   loader : 類加載器
     * interfaces : 實(shí)現(xiàn)接口
     * h InvocationHandler
     */
     Moveable m= (Moveable)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
     //執(zhí)行被代理類的方法
     m.move();
   }
 
 }

使用CGLIB動(dòng)態(tài)代理實(shí)現(xiàn)的例子:

  1.創(chuàng)建代理類,實(shí)現(xiàn)MethodInterceptor接口

  2.使用Enhancer類創(chuàng)建代理方法

  3.創(chuàng)建被代理類,并編寫代理方法

  4.通過代理調(diào)用方法

/**
 * 使用cglib動(dòng)態(tài)代理
 * @author Administrator
 *
 */
public class Train {
  public void move(){
    System.out.println("火車行駛中。。。");
  }
}
public class CglibProxy implements MethodInterceptor {

  private Enhancer enhancer = new Enhancer();
  //創(chuàng)建代理類方法
  public Object getProxy(Class clazz){
    //設(shè)置創(chuàng)建子類的類
    enhancer.setSuperclass(clazz);
    //回調(diào)函數(shù)
    enhancer.setCallback(this);
    //創(chuàng)建并返回子類的實(shí)例
    return enhancer.create();
  }
  /**
   * 作用:攔截所有目標(biāo)類方法的調(diào)用
   * obj : 目標(biāo)類的實(shí)例
   * m : 目標(biāo)方法的反射對(duì)象
   * args : 方法的參數(shù)
   * proxy : 代理類的實(shí)例
   */
  @Override
  public Object intercept(Object obj, Method m, Object[] args, MethodProxy proxy) throws Throwable {
    //在調(diào)用方法時(shí)實(shí)現(xiàn)自己的業(yè)務(wù)邏輯
    System.out.println("日志開始...");
    //代理類調(diào)用父類的方法
    proxy.invokeSuper(obj, args);
    //調(diào)用方法之后實(shí)現(xiàn)自己的業(yè)務(wù)邏輯
    System.out.println("日志結(jié)束...");
    return null;
  }
}
 /**
  * 使用cglib動(dòng)態(tài)代理的測(cè)試類
  * @author Administrator
  *
  */
 public class CglibProxyTest {
 
   public static void main(String[] args) {
     CglibProxy proxy = new CglibProxy();
     //傳入要代理的類
     Train t = (Train)proxy.getProxy(Train.class);
     //執(zhí)行方法
     t.move();
   }
 
 }

以上就是詳解JAVA設(shè)計(jì)模式之代理模式的詳細(xì)內(nèi)容,更多關(guān)于JAVA 代理模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • httpclient提交json參數(shù)的示例詳解

    httpclient提交json參數(shù)的示例詳解

    httpclient使用post提交json參數(shù),和使用表單提交區(qū)分,本文結(jié)合示例代碼講解的非常詳細(xì),補(bǔ)充介紹了HttpClient請(qǐng)求傳json參數(shù)的案例代碼,感興趣的朋友一起看看吧
    2024-02-02
  • springboot中redis的緩存穿透問題實(shí)現(xiàn)

    springboot中redis的緩存穿透問題實(shí)現(xiàn)

    這篇文章主要介紹了springboot中redis的緩存穿透問題實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 一文了解Spring中攔截器的原理與使用

    一文了解Spring中攔截器的原理與使用

    在web開發(fā)中,攔截器是經(jīng)常用到的功能。它可以幫我們預(yù)先設(shè)置數(shù)據(jù)以及統(tǒng)計(jì)方法的執(zhí)行效率等等。今天就來詳細(xì)的談一下spring中的攔截器,需要的可以參考一下
    2022-06-06
  • Spring Boot jar 啟動(dòng)時(shí)設(shè)置環(huán)境參數(shù)的操作

    Spring Boot jar 啟動(dòng)時(shí)設(shè)置環(huán)境參數(shù)的操作

    這篇文章主要介紹了Spring Boot jar 啟動(dòng)時(shí)設(shè)置環(huán)境參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java接口Array介紹

    java接口Array介紹

    這篇文章主要介紹了java接口Array的相關(guān)資料,需要的朋友可以參考下
    2014-10-10
  • SpringBoot?如何將項(xiàng)目打包成?jar?包

    SpringBoot?如何將項(xiàng)目打包成?jar?包

    這篇文章主要介紹了SpringBoot如何將項(xiàng)目打包成jar包,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • java LRU(Least Recently Used )詳解及實(shí)例代碼

    java LRU(Least Recently Used )詳解及實(shí)例代碼

    這篇文章主要介紹了java LRU(Least Recently Used )詳解及實(shí)例代碼的相關(guān)資料,Java里面實(shí)現(xiàn)LRU緩存通常有兩種選擇,一種是使用LinkedHashMap,一種是自己設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),使用鏈表+HashMap,需要的朋友可以參考下
    2016-11-11
  • SpringBoot3.0整合chatGPT的完整步驟

    SpringBoot3.0整合chatGPT的完整步驟

    ChatGPT是OpenAI推出的一個(gè)語言模型系統(tǒng),它能夠?qū)崟r(shí)回答用戶提問,包括聊天、糾正語法錯(cuò)誤,甚至是寫代碼、寫劇本等,由于可玩性很高,迅速在全球范圍內(nèi)風(fēng)靡起來,下面這篇文章主要給大家介紹了關(guān)于SpringBoot3.0整合chatGPT的完整步驟,需要的朋友可以參考下
    2022-12-12
  • java獲取客服端信息的方法(系統(tǒng),瀏覽器等)

    java獲取客服端信息的方法(系統(tǒng),瀏覽器等)

    下面小編就為大家?guī)硪黄猨ava獲取客服端信息的方法(系統(tǒng),瀏覽器等)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-09-09
  • mybatis查詢匹配機(jī)制圖文詳解

    mybatis查詢匹配機(jī)制圖文詳解

    這篇文章主要給大家介紹了關(guān)于mybatis查詢匹配機(jī)制的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評(píng)論

肃北| 腾冲县| 屯门区| 台湾省| 北票市| 韶山市| 瓦房店市| 五峰| 平邑县| 武安市| 宜阳县| 水富县| 钟山县| 明光市| 酒泉市| 东丽区| 瓮安县| 吉安市| 玉树县| 永靖县| 禄丰县| 平湖市| 西城区| 丰镇市| 田阳县| 商城县| 大邑县| 清流县| 安塞县| 遵义市| 若羌县| 贺兰县| 洛阳市| 河东区| 汪清县| 东方市| 贞丰县| 洛扎县| 金寨县| 霞浦县| 苍溪县|