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

Java動(dòng)態(tài)代理的兩種實(shí)現(xiàn)方式詳解【附相關(guān)jar文件下載】

 更新時(shí)間:2019年03月08日 11:21:24   作者:Bug開(kāi)發(fā)攻城獅  
這篇文章主要介紹了Java動(dòng)態(tài)代理的兩種實(shí)現(xiàn)方式,結(jié)合實(shí)例形式分析了java動(dòng)態(tài)代理的相關(guān)原理、實(shí)現(xiàn)方法與操作技巧,并附帶相關(guān)jar文件供讀者下載,需要的朋友可以參考下

本文實(shí)例講述了Java動(dòng)態(tài)代理的兩種實(shí)現(xiàn)方式。分享給大家供大家參考,具體如下:

一說(shuō)到動(dòng)態(tài)代理,我們第一個(gè)想到肯定是大名鼎鼎的Spring AOP了。在AOP的源碼中用到了兩種動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)攔截切入功能:jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理。兩種方法同時(shí)存在,各有優(yōu)劣。jdk動(dòng)態(tài)代理是由java內(nèi)部的反射機(jī)制來(lái)實(shí)現(xiàn)的,cglib動(dòng)態(tài)代理是通過(guò)繼承來(lái)實(shí)現(xiàn)的,底層則是借助asm(Java 字節(jié)碼操控框架)來(lái)實(shí)現(xiàn)的(采用字節(jié)碼的方式,給A類創(chuàng)建一個(gè)子類B,子類B使用方法攔截的技術(shù)攔截所以父類的方法調(diào)用)??偟膩?lái)說(shuō),反射機(jī)制在生成類的過(guò)程中比較高效,而asm在生成類之后的相關(guān)執(zhí)行過(guò)程中比較高效(可以通過(guò)將asm生成的類進(jìn)行緩存,這樣解決asm生成類過(guò)程低效問(wèn)題)。還有一點(diǎn)必須注意:jdk動(dòng)態(tài)代理的應(yīng)用前提,必須是目標(biāo)類基于統(tǒng)一的接口。如果沒(méi)有上述前提,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ì)。。

公用的接口和實(shí)現(xiàn)類

public interface UserService {
  public String getName(int id);
  public Integer getAge(int id);
}
public class UserServiceImpl implements UserService {
  @Override
  public String getName(int id) {
    System.out.println("------getName------");
    return "Tom";
  }
  @Override
  public Integer getAge(int id) {
    System.out.println("------getAge------");
    return 10;
  }
}

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

jdk的動(dòng)態(tài)代理,依賴的是反射包下的invocationHandler接口,我們的代理類實(shí)現(xiàn)invocationHandler,重寫(xiě)invoke()方法,每當(dāng)我們的代理類調(diào)用方法時(shí),都會(huì)默認(rèn)先經(jīng)過(guò)invoke()方法。

public class UserInvocationHandler implements InvocationHandler {
  private Object target;
  UserInvocationHandler() {
    super();
  }
  UserInvocationHandler(Object target) {
    super();
    this.target = target;
  }
  @Override
  public Object invoke(Object o, Method method, Object[] args) throws Throwable {
    if("getName".equals(method.getName())){
      System.out.println("++++++before " + method.getName() + "++++++");
      Object result = method.invoke(target, args);
      System.out.println("++++++after " + method.getName() + "++++++");
      return result;
    }else{
      Object result = method.invoke(target, args);
      return result;
    }
  }
}

測(cè)試類

public class M {
  public static void main(String[] args) {
    UserService userService = new UserServiceImpl();
    InvocationHandler invocationHandler = new UserInvocationHandler(userService);
    UserService userServiceProxy = (UserService) Proxy.newProxyInstance(
        userService.getClass().getClassLoader(),
        userService.getClass().getInterfaces(),
        invocationHandler);
    System.out.println(userServiceProxy.getName(1));
    System.out.println(userServiceProxy.getAge(1));
  }
}

測(cè)試效果

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

cglib依賴的是cglib包下的methodInterceptor接口,每調(diào)用代理類的方法,都會(huì)調(diào)用intercept方法

public class CglibMethodInterceptor implements MethodInterceptor {
  @Override
  public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    System.out.println("------before " + methodProxy.getSuperName() + "------");
    Object o1 = methodProxy.invokeSuper(o, args);
    System.out.println("------after " + methodProxy.getSuperName() + "------");
    return o1;
  }
}

測(cè)試類

public class M {
  public static void main(String[] args) {
    CglibMethodInterceptor cglibProxy = new CglibMethodInterceptor();
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(UserServiceImpl.class);
    enhancer.setCallback(cglibProxy);
    UserService o = (UserService) enhancer.create();
    o.getName(1);
    o.getAge(1);
  }
}

測(cè)試結(jié)果

ps:cglib的動(dòng)態(tài)代理,需要cglib.jarasm.jar支持

附:點(diǎn)擊此處本站下載 cglib.jar  asm.jar 。

更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Struts2動(dòng)態(tài)結(jié)果集代碼示例

    Struts2動(dòng)態(tài)結(jié)果集代碼示例

    這篇文章主要介紹了Struts2動(dòng)態(tài)結(jié)果集的有關(guān)內(nèi)容,涉及具體代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-09-09
  • Spring中的aware接口詳情

    Spring中的aware接口詳情

    這篇文章主要介紹了Spring中的aware接口詳情,Spring中有很多繼承于aware中的接口,這些接口到底是做什么用到的,下面我們就一起來(lái)看看吧,文章詳細(xì)內(nèi)容需要的小伙伴可以參考一下
    2022-05-05
  • java Runtime如何執(zhí)行多條命令

    java Runtime如何執(zhí)行多條命令

    這篇文章主要介紹了java Runtime如何執(zhí)行多條命令,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Jemalloc優(yōu)化MySQL和Nginx

    Jemalloc優(yōu)化MySQL和Nginx

    這篇文章主要介紹了Jemalloc優(yōu)化MySQL和Nginx的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • Spring Security在標(biāo)準(zhǔn)登錄表單中添加一個(gè)額外的字段

    Spring Security在標(biāo)準(zhǔn)登錄表單中添加一個(gè)額外的字段

    這篇文章主要介紹了Spring Security在標(biāo)準(zhǔn)登錄表單中添加一個(gè)額外的字段,我們將重點(diǎn)關(guān)注兩種不同的方法,以展示框架的多功能性以及我們可以使用它的靈活方式。 需要的朋友可以參考下
    2019-05-05
  • 詳解spring boot實(shí)現(xiàn)多數(shù)據(jù)源代碼實(shí)戰(zhàn)

    詳解spring boot實(shí)現(xiàn)多數(shù)據(jù)源代碼實(shí)戰(zhàn)

    本篇文章主要介紹了詳解spring boot實(shí)現(xiàn)多數(shù)據(jù)源代碼實(shí)戰(zhàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Java中Lambda表達(dá)式的使用詳細(xì)教程

    Java中Lambda表達(dá)式的使用詳細(xì)教程

    這篇文章將通過(guò)示例為大家詳細(xì)展示Java中Lambda表達(dá)式的用法,同時(shí)也會(huì)介紹Lambda的相關(guān)知識(shí),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-05-05
  • 實(shí)例講解MyBatis如何防止SQL注入

    實(shí)例講解MyBatis如何防止SQL注入

    這篇文章通過(guò)實(shí)例代碼介紹MyBatis如何防止SQL注入,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • 使用System.exit()來(lái)優(yōu)雅地終止SpringBoot項(xiàng)目的代碼示例

    使用System.exit()來(lái)優(yōu)雅地終止SpringBoot項(xiàng)目的代碼示例

    System.exit() 方法是 Java 中用于退出程序的方法,它接受一個(gè)整數(shù)參數(shù),通常被用來(lái)指示程序的退出狀態(tài),本文給大家介紹了如何使用System.exit()來(lái)優(yōu)雅地終止SpringBoot項(xiàng)目,需要的朋友可以參考下
    2024-08-08
  • SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析

    SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析

    這篇文章主要介紹了SpringBoot應(yīng)用為什么能直接運(yùn)行java -jar,首先明確一點(diǎn),普通jar包是不能直接運(yùn)行的,比如工具類jar,要能運(yùn)行,至少得要一個(gè)main函數(shù)作為入口吧?本文給大家介紹了詳細(xì)的原因分析,需要的朋友可以參考下
    2024-03-03

最新評(píng)論