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

深入理解java動(dòng)態(tài)代理的兩種實(shí)現(xiàn)方式(JDK/Cglib)

 更新時(shí)間:2017年04月05日 09:09:00   作者:PerKins.Zhu  
本篇文章主要介紹了java動(dòng)態(tài)代理的兩種實(shí)現(xiàn)方式,詳細(xì)的介紹了JDK和Cglib的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,有興趣的可以了解一下

什么是代理模式?

代理模式:在調(diào)用處不直接調(diào)用目標(biāo)類進(jìn)行操作,而是調(diào)用代理類,然后通過代理類來調(diào)用目標(biāo)類進(jìn)行操作。在代理類調(diào)用目標(biāo)類的前后可以添加一些預(yù)處理和后處理操作來完成一些不屬于目標(biāo)類的功能。

為什么要使用代理模式?

通過代理模式可以實(shí)現(xiàn)對(duì)目標(biāo)類調(diào)用的控制、在目標(biāo)類調(diào)用前/后進(jìn)行一些不屬于目標(biāo)類的操作,如:數(shù)據(jù)驗(yàn)證、預(yù)處理、后處理、異常處理等

什么是靜態(tài)代理什么是動(dòng)態(tài)代理?

  1. 靜態(tài)代理:代理類只能實(shí)現(xiàn)對(duì)”特定接口的實(shí)現(xiàn)類“進(jìn)行代理
  2. 動(dòng)態(tài)代理:代理類可以實(shí)現(xiàn)對(duì)多種類的代理

jdk代理和cglib代理區(qū)別在哪里?

  1. jdk動(dòng)態(tài)代理:代理所有“實(shí)現(xiàn)的有接口”的目標(biāo)類
  2. cglib動(dòng)態(tài)代理:代理任意一個(gè)目標(biāo)類,但對(duì)final類和方法無法代理

不同點(diǎn):jdk動(dòng)態(tài)代理的目標(biāo)類必須實(shí)現(xiàn)的有接口,因?yàn)樵谡{(diào)用Proxy.newProxyInstance()的時(shí)候需要傳入目標(biāo)類的接口類。而cglib不做此限制。    

下面看代碼分析:

定義一個(gè)Person接口

package com.zpj.designMode.proxy;

//定義一個(gè)Person接口
public interface Person {
  public void doWork();
}

添加一個(gè)實(shí)現(xiàn)類:MrLi

package com.zpj.designMode.proxy;

//添加一個(gè)實(shí)現(xiàn)類
public class MrLi implements Person {

  @Override
  public void doWork() {
    System.out.println("-----doWork");
  }

}

靜態(tài)代理:

添加一個(gè)靜態(tài)代理類Proxy

package com.zpj.designMode.proxy;

//靜態(tài)代理,代理必須和目標(biāo)類實(shí)現(xiàn)共同的接口
public class Proxy implements Person {
  private Person person;// 被代理人

  //這里的目標(biāo)類型決定了該代理類只能代理實(shí)現(xiàn)了Person接口的實(shí)例,而不能接收其他類型參數(shù),這也就是靜態(tài)代理的局限性
  public Proxy(Person person) {
    this.person = person;
  }

  @Override
  public void doWork() {
    System.out.println("doSomething-----start");
    person.doWork();
    System.out.println("doSomething-----end");
  }

}

靜態(tài)代理測(cè)試程序:

package com.zpj.designMode.proxy;

public class Run {
  public static void main(String[] args) {
    MrLi li = new MrLi();
    Proxy proxy = new Proxy(li);
    //調(diào)用處直接調(diào)用代理進(jìn)行目標(biāo)方法的操作。
    proxy.doWork();
  }
}

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

添加一個(gè)代理JDKProxy,該代理實(shí)現(xiàn)InvocationHandler接口且覆寫invoke方法。

package com.zpj.designMode.proxy.jdk;

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

/***
 @author Perkins Zhu
 @date 2017年3月13日 上午8:41:10
 */
public class JDKProxy implements InvocationHandler {

  private Object person;// 被代理人
   
  
  //這里的目標(biāo)類型為Object,則可以接受任意一種參數(shù)作為被代理類,實(shí)現(xiàn)了動(dòng)態(tài)代理。但是要注意下面的newProxyInstance()中的參數(shù)
  public Object getInstance(Object person) {
    this.person = person;
    //與cglib的區(qū)別在于這里構(gòu)建代理對(duì)象的時(shí)候需要傳入被代理對(duì)象的接口對(duì)象,第二個(gè)參數(shù)。而cglib不需要被代理對(duì)象實(shí)現(xiàn)任何接口即可    
    return Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), this);
  }

 

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("doSomething---------start");
    method.invoke(person, args);
    System.out.println("doSomething---------end");
    return null;
  }

}

JDK動(dòng)態(tài)代理測(cè)試程序

package com.zpj.designMode.proxy.jdk;

import com.zpj.designMode.proxy.MrLi;
import com.zpj.designMode.proxy.Person;

/***
 * @author Perkins Zhu
 * @date 2017年3月13日 上午8:51:31
 */
public class Run {

  public static void main(String[] args) {
    Person person = (Person) new JDKProxy().getInstance(new MrLi());
    //注意這里的person不是目標(biāo)類person,而是代理類person:debug的時(shí)候顯示null,有'$'標(biāo)識(shí)符
    person.doWork();
  }
}

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

添加一個(gè)CglibProxy代理,同時(shí)實(shí)現(xiàn)MethodInterceptor接口。

package com.zpj.designMode.proxy.cglib;

import java.lang.reflect.Method;

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

/***
 * @author Perkins Zhu
 * @date 2017年3月13日 上午9:02:54
 */
public class CglibProxy implements MethodInterceptor {
  private Object targetObject;

  // 這里的目標(biāo)類型為Object,則可以接受任意一種參數(shù)作為被代理類,實(shí)現(xiàn)了動(dòng)態(tài)代理
  public Object getInstance(Object target) {
    this.targetObject = target;
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(target.getClass());
    enhancer.setCallback(this);
    //注意該處代理的創(chuàng)建過程
    Object proxyObj = enhancer.create();
    return proxyObj;// 返回代理對(duì)象
  }

  @Override
  public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    Object obj = null;
    System.out.println("doSomething---------start");
    obj = method.invoke(targetObject, args);
    System.out.println("doSomething---------end");
    return obj;
  }

}

Cglib動(dòng)態(tài)代理測(cè)試程序

package com.zpj.designMode.proxy.cglib;

import com.zpj.designMode.proxy.MrLi;
import com.zpj.designMode.proxy.Person;

/***
 @author Perkins Zhu
 @date 2017年3月13日 上午9:07:38
 */
public class Run {

  public static void main(String[] args) {
    Person person = (Person)new CglibProxy().getInstance(new MrLi());
    person.doWork();
  }
}

仔細(xì)對(duì)比Proxy、CglibProxy和JDKProxy區(qū)分靜態(tài)代理、JDK動(dòng)態(tài)代理和Cglib動(dòng)態(tài)代理的異同點(diǎn)!

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

相關(guān)文章

  • 關(guān)于@PropertySource配置的用法解析

    關(guān)于@PropertySource配置的用法解析

    這篇文章主要介紹了關(guān)于@PropertySource配置的用法解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 一文帶你徹底明白什么是Java注解

    一文帶你徹底明白什么是Java注解

    Java注解可以說是我們編碼過程中最常用的,本文將給大家介紹Java注解的概念、作用以及如何使用注解來提升代碼的可讀性和靈活性,需要的可以參考一下
    2023-05-05
  • Spring bean的實(shí)例化和IOC依賴注入詳解

    Spring bean的實(shí)例化和IOC依賴注入詳解

    這篇文章主要介紹了Spring bean的實(shí)例化和IOC依賴注入詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • springboot利用AOP完成日志統(tǒng)計(jì)的詳細(xì)步驟

    springboot利用AOP完成日志統(tǒng)計(jì)的詳細(xì)步驟

    項(xiàng)目用到了過濾器,可能有的人會(huì)不理解,之所以用過濾器是因?yàn)橄胍谌罩居涗沺ost請(qǐng)求的json數(shù)據(jù)。本文重點(diǎn)給大家介紹springboot利用AOP完成日志統(tǒng)計(jì)的詳細(xì)步驟,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • springboot項(xiàng)目集成swagger-bootstrap-ui全過程

    springboot項(xiàng)目集成swagger-bootstrap-ui全過程

    這篇文章主要介紹了springboot項(xiàng)目集成swagger-bootstrap-ui全過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • SpringBoot如何使用Fastjson解析Json數(shù)據(jù)

    SpringBoot如何使用Fastjson解析Json數(shù)據(jù)

    這篇文章主要介紹了SpringBoot如何使用Fastjson解析Json數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java使用BigDecimal進(jìn)行運(yùn)算封裝的實(shí)際案例

    Java使用BigDecimal進(jìn)行運(yùn)算封裝的實(shí)際案例

    今天小編就為大家分享一篇關(guān)于Java使用BigDecimal進(jìn)行運(yùn)算封裝的實(shí)際案例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • java實(shí)現(xiàn)KFC點(diǎn)餐系統(tǒng)

    java實(shí)現(xiàn)KFC點(diǎn)餐系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)KFC點(diǎn)餐系統(tǒng),模擬肯德基快餐店的收銀系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 全面解讀Java?NIO(看這篇就夠了)

    全面解讀Java?NIO(看這篇就夠了)

    Java?NIO是Java1.4之后推出來的一套IO接口,NIO提供了一種完全不同的操作方式,?NIO支持面向緩沖區(qū)的、基于通道的IO操作,這篇文章主要介紹了Java?NIO詳解(看這篇就夠了),需要的朋友可以參考下
    2023-05-05
  • 解決@PathVariable出現(xiàn)點(diǎn)號(hào).時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問題

    解決@PathVariable出現(xiàn)點(diǎn)號(hào).時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問題

    這篇文章主要介紹了解決@PathVariable出現(xiàn)點(diǎn)號(hào).時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評(píng)論