日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

利用代码分别实现jdk动态代理和cglib动态代理_面试之动态代理

發布時間:2025/3/12 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用代码分别实现jdk动态代理和cglib动态代理_面试之动态代理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好!我是CSRobot,從今天開始,我將會發布一些技術文章,內容就是結合春招以來的面試所遇到的問題進行分享,首先會對知識點進行一個探討和整理,在最后會給出一些面試題并作出解答,希望可以幫助到大家!今天知識點是動態代理,會分從以下幾個方面進行探討:

  • 靜態代理
  • JDK動態代理
  • Cglib動態代理
  • 面試題分享

在java中,要說到動態代理,那么首先需要聊聊靜態代理

一、靜態代理

靜態代理是代理類在編譯期間就創建好了,不是編譯器生成的代理類,而是手動創建的類。在編譯時就已經將接口,被代理類,代理類等確定下來。以下以一個例子來說明靜態代理的實現

1、實現步驟

  • 創建服務類接口:BuyHouse
//創建服務接口 public interface BuyHouse {void buyHouse(); }
  • 實現服務接口: BuyHouseImpl
//實現接口 public class BuyHouseImpl implements BuyHouse {@Overridepublic void buyHouse() {System.out.println("我要買房子!");} }
  • 創建代理類實現服務接口,在代理類中手動增強: BuyHouseProxy
public class BuyHouseProxy implements BuyHouse {private BuyHouse buyHouse;public BuyHouseProxy(final BuyHouse buyHouse) {this.buyHouse = buyHouse;}//手動增強buyHouse方法@Overridepublic void buyHouse() {System.out.println("買房前準備");buyHouse.buyHouse();System.out.println("買房后裝修");} }
  • 創建測試類
@Test public void test() {//未增強的類BuyHouse buyHouse = new BuyHouseImpl();buyHouse.buyHouse();//創建代理類BuyHouseProxy buyHouseProxy = new BuyHouseProxy(buyHouse);buyHouseProxy.buyHouse(); }
  • 輸出:
我要買房子!
買房前準備
我要買房子!
買房后裝修

二、動態代理

? Java動態代理的優勢是實現無侵入式的代碼擴展,也就是方法的增強;讓你可以在不用修改源碼的情況下,增強一些方法;在方法的前后你可以做你任何想做的事情。

? 在java的動態代理中,主要有兩種實現方式,首先是基于反射的JDK動態代理實現;其次是cglib的字節碼技術的實現

1、JDK動態代理

  • 通過實現 InvocationHandler 接口創建自己的調用處理器
  • 通過為 Proxy 類指定 ClassLoader 對象和一組 interface 來創建動態代理類
  • 通過反射機制獲得動態代理類的構造函數,其唯一參數類型是調用處理器接口類型
  • 通過構造函數創建動態代理類實例,構造時調用處理器對象作為參數被傳入
  • 代理類名稱是包名+$Proxy+id序號
  • JDK動態代理只能代理接口而不能代理類,原因大家可以根據jdk動態代理的實現步驟大膽推斷一下,后文會給出答案
  • 創建服務接口
//創建服務接口 public interface BuyHouse {void buyHouse(); }public class BuyHouseImpl implements BuyHouse {@Overridepublic void buyHouse() {System.out.println("我要買房子!");} }
  • 編寫動態處理器
public class DynamicProxyHandler implements InvocationHandler{private Object object;public DynamicProxyHandler(final Object object) {this.object = object;}//invoke方法對業務進行增強@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("買房前準備");Object result = method.invoke(object, args);System.out.println("買房后裝修");return result;}public Object getProxyInstance(){return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);} }
  • 測試動態代理
@Testpublic void test1() {//創建需要被代理的類BuyHouse buyHouse = new BuyHouseImpl();//創建動態代理處理器DynamicProxyHandler DP = new DynamicProxyHandler(buyHouse);//獲得代理類BuyHouse proxyBuyHouse = DP.getProxyInstance();proxyBuyHouse.buyHouse();}
  • 輸出
買房前準備
我要買房子!
買房后裝修

2、Cglib動態代理

在cglib中提供了一個Enhance類來創建代理類,類似于jdk動態代理中的Proxy類。

  • 添加maven依賴包
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>2.2.2</version> </dependency>
  • 同樣是使用上文中buyHouse的類
//創建服務接口 public interface BuyHouse {void buyHouse(); }public class BuyHouseImpl implements BuyHouse {@Overridepublic void buyHouse() {System.out.println("我要買房子!");} }
  • 創建方法攔截器
public class CglibProxy implements MethodInterceptor{private Object target;public Object getInstance(final Object target) {this.target = target;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(this.target.getClass());enhancer.setCallback(this);return enhancer.create();}@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("買房前準備");Object result = proxy.invokeSuper(obj, args);System.out.println("買房后裝修");return result;} }
  • 測試
@Test public void test3(){BuyHouse buyHouse = new BuyHouseImpl();CglibProxy cglibProxy = new CglibProxy();BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl)cglibProxy.getInstance(buyHouse);buyHouseCglibProxy.buyHouse(); }
  • 最終輸出結果和之前相同

三、面試題

1、動態代理是什么?

動態代理:為其他對象提供一個代理以控制對某個對象的訪問。代理類主要負責為委托了(真實對象)預處理消息、過濾消息、傳遞消息給委托類,代理類不現實具體服務,而是利用委托類來完成服務,并將執行結果封裝處理

2、為什么不使用靜態代理而使用動態代理?

通過前文大家也可以理解了,靜態代理是代理類在編譯期間就創建好了,不是編譯器生成的代理類,需要手動創建的類。在編譯時就已經將接口,被代理類,代理類等確定下來。如果我們有很多類很多接口需要代理,那么我們就只能使用代碼提前寫死,不夠靈活;使用了動態代理之后,我們不需要手動創建代理類,全部交給代理去完成對代理類的創建,實現無侵入式的代碼擴展,這也是符合面向對象編程原則的操作。

3、JDK動態代理為什么只能代理接口而不能代理類?

通過JDK動態代理實現步驟我們就可以看到,我們通過Proxy類的newProxyInstance方法來生成代理對象,代理類繼承了Proxy類并且實現了要代理的接口,由于java不支持多繼承,所以JDK動態代理不能代理類

4、JDK動態代理和CgLib動態代理的區別?

1)JDK動態代理只能代理接口而不能代理類,CgLib對于接口和類都可以實現代理

2)JDK動態代理底層使用反射的方式實現;而CgLib采用了非常底層的字節碼技術,其原理是通過目標類的字節碼為一個類創建子類,并在子類中采用方法攔截的技術攔截所有父類方法的調用,順勢織入橫切邏輯。代理類將目標類作為自己的父類并為其中的每個非final委托方法創建兩個方法

CSRobot

總結

以上是生活随笔為你收集整理的利用代码分别实现jdk动态代理和cglib动态代理_面试之动态代理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。