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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

实战CGLib系列之proxy:方法拦截MethodInterceptor

發布時間:2023/12/10 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实战CGLib系列之proxy:方法拦截MethodInterceptor 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、首先說一下JDK中的動態代理

JDK中的動態代理是通過反射類Proxy以及InvocationHandler回調接口實現的,但是,JDK中所要進行動態代理的類必須要實現一個接口,也就是說只能對該類所實現接口中定義的方法進行代理,這在實際編程中具有一定的局限性,而且使用反射的效率也并不是很高。

二、使用CGLib實現

使用CGLib實現動態代理,完全不受代理類必須實現接口的限制,而且CGLib底層采用ASM字節碼生成框架,使用字節碼技術生成代理類,比使用Java反射效率要高。唯一需要注意的是,CGLib不能對聲明為final的方法進行代理,因為CGLib原理是動態生成被代理類的子類。

下面,將通過一個實例介紹使用CGLib實現動態代理。

1、被代理類

首先,定義一個類,該類沒有實現任何接口,包含兩個方法。

public class ConcreteClassNoInterface {public String getConcreteMethodA(String str){System.out.println("ConcreteMethod A ... "+str);return str;}public int getConcreteMethodB(int n){System.out.println("ConcreteMethod B ... "+n);return n+10;} }

2、攔截器

定義一個攔截器。在調用目標方法時,CGLib會回調MethodInterceptor接口方法攔截,來實現你自己的代理邏輯,類似于JDK中的InvocationHandler接口。

public class ConcreteClassInterceptor implements MethodInterceptor{public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {System.out.println("Before:"+method); Object object=proxy.invokeSuper(obj, arg);System.out.println("After:"+method); return object;} }

參數:Object為由CGLib動態生成的代理類實例,Method為上文中實體類所調用的被代理的方法引用,Object[]為參數值列表,MethodProxy為生成的代理類對方法的代理引用。

返回:從代理實例的方法調用返回的值。

其中,proxy.invokeSuper(obj,arg):

調用代理類實例上的proxy方法的父類方法(即實體類ConcreteClassNoInterface中對應的方法)

在這個示例中,只在調用被代理類方法前后各打印了一句話,當然實際編程中可以是其它復雜邏輯。

3、生成動態代理類

Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(ConcreteClassNoInterface.class); enhancer.setCallback(new ConcreteClassInterceptor()); ConcreteClassNoInterface ccni=(ConcreteClassNoInterface)enhancer.create();

這里Enhancer類是CGLib中的一個字節碼增強器,它可以方便的對你想要處理的類進行擴展,以后會經常看到它。

首先將被代理類ConcreteClassNoInterface設置成父類,然后設置攔截器ConcreteClassInterceptor,最后執行enhancer.create()動態生成一個代理類,并從Object強制轉型成父類型ConcreteClassNoInterface。

最后,在代理類上調用方法:

Java代碼??
  • ccni.getConcreteMethodA("shensy");??
  • ccni.getConcreteMethodB(0);??
  • 查看控制臺輸出:

    控制臺代碼??
  • Before?:public?java.lang.String?generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String)??
  • ConcreteMethod?A?...?shensy??
  • After?:public?java.lang.String?generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodA(java.lang.String)??
  • Before?:public?int?generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int)??
  • ConcreteMethod?B?...?0??
  • After?:public?int?generic.cglib.proxy.ConcreteClassNoInterface.getConcreteMethodB(int)??
  • 可以看到,攔截器在調用被代理類方法前后都執行了print操作。





    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的实战CGLib系列之proxy:方法拦截MethodInterceptor的全部內容,希望文章能夠幫你解決所遇到的問題。

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