国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

Java動態代理的兩種實現方式詳解【附相關jar文件下載】

2024-07-14 08:43:55
字體:
來源:轉載
供稿:網友

本文實例講述了Java動態代理的兩種實現方式。分享給大家供大家參考,具體如下:

一說到動態代理,我們第一個想到肯定是大名鼎鼎的Spring AOP了。在AOP的源碼中用到了兩種動態代理來實現攔截切入功能:jdk動態代理和cglib動態代理。兩種方法同時存在,各有優劣。jdk動態代理是由java內部的反射機制來實現的,cglib動態代理是通過繼承來實現的,底層則是借助asm(Java 字節碼操控框架)來實現的(采用字節碼的方式,給A類創建一個子類B,子類B使用方法攔截的技術攔截所以父類的方法調用)。總的來說,反射機制在生成類的過程中比較高效,而asm在生成類之后的相關執行過程中比較高效(可以通過將asm生成的類進行緩存,這樣解決asm生成類過程低效問題)。還有一點必須注意:jdk動態代理的應用前提,必須是目標類基于統一的接口。如果沒有上述前提,jdk動態代理不能應用。由此可以看出,jdk動態代理有一定的局限性,cglib這種第三方類庫實現的動態代理應用更加廣泛,且在效率上更有優勢。。

公用的接口和實現類

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的動態代理實現

jdk的動態代理,依賴的是反射包下的invocationHandler接口,我們的代理類實現invocationHandler,重寫invoke()方法,每當我們的代理類調用方法時,都會默認先經過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;    }  }}

測試類

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));  }}

測試效果

Java,動態代理,jar,文件下載

CGLIB的動態代理實現

cglib依賴的是cglib包下的methodInterceptor接口,每調用代理類的方法,都會調用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;  }}

測試類

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);  }}

測試結果

Java,動態代理,jar,文件下載

ps:cglib的動態代理,需要cglib.jarasm.jar支持

附:點擊此處本站下載 cglib.jar  asm.jar 。

希望本文所述對大家java程序設計有所幫助。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 雅安市| 新巴尔虎左旗| 天峨县| 泗洪县| 兰坪| 南充市| 东至县| 武宁县| 高雄县| 丰都县| 青河县| 绍兴县| 杂多县| 观塘区| 新宁县| 马鞍山市| 宜章县| 册亨县| 重庆市| 高陵县| 雷波县| 崇明县| 砚山县| 台前县| 临夏市| 宜兴市| 许昌县| 汝南县| 元江| 门头沟区| 常山县| 辽宁省| 绥芬河市| 丰城市| 绥化市| 洪洞县| 韶关市| 军事| 武强县| 峡江县| 克东县|