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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java-CGLib动态代理

發(fā)布時間:2025/3/21 java 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java-CGLib动态代理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 導(dǎo)讀
  • 問題
  • CGLib動態(tài)代理和JDK動態(tài)代理的區(qū)別
  • CGLib概述
  • 改造

導(dǎo)讀

Spring-AOP基礎(chǔ)知識

Java-JDK動態(tài)代理

Java-CGLib動態(tài)代理


問題

另一篇博文中的問題

性能監(jiān)視橫切邏輯代碼


CGLib動態(tài)代理和JDK動態(tài)代理的區(qū)別

我們知道使用JDK創(chuàng)建代理時只能為接口創(chuàng)建代理實(shí)例。我們從Proxy的newProxyInstance方法中可以看出

@CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

第二個參數(shù)interfaces就是需要代理實(shí)例實(shí)現(xiàn)的接口列表。

對于沒有通用接口定義業(yè)務(wù)方法的類,該如何動態(tài)創(chuàng)建代理實(shí)例呢?
JDK動態(tài)代理技術(shù)顯然無能為力了,CGLib作為一個替代者,很好地解決了這個問題


CGLib概述

CGLib采用底層的字節(jié)碼技術(shù),可以為一個類創(chuàng)建子類,在子類中采用方法攔截的技術(shù)攔截所有父類方法的調(diào)用并順勢織入橫切邏輯。


改造

代碼已托管到Github—> https://github.com/yangshangwei/SpringMaster

首先在我們的java maven工程中 添加依賴

<!-- https://mvnrepository.com/artifact/cglib/cglib --><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>${cglib.version}</version></dependency>

使用的版本為 3.2.5

package com.xgj.aop.base.cglib;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;public class CglibProxy implements MethodInterceptor {private Enhancer enhancer = new Enhancer();public Object getProxy(Class clazz) {// 設(shè)置需要創(chuàng)建的子類的類enhancer.setSuperclass(clazz);enhancer.setCallback(this);// 通過字節(jié)碼動態(tài)創(chuàng)建子類實(shí)例return enhancer.create();}// 攔截父類所有方法的調(diào)用@Overridepublic Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {// 橫切邏輯代碼PerformanceMonitor.begin(obj.getClass().getName() + "."+ method.getName());// 業(yè)務(wù)邏輯,通過代理類調(diào)用父類中的方法Object result = proxy.invokeSuper(obj, args);// 橫切邏輯代碼PerformanceMonitor.end();return result;}}

上述代碼,我們通過getProxy(Class clazz)方法為一個類創(chuàng)建動態(tài)代理對象,該代理對象通過擴(kuò)展clazz實(shí)現(xiàn)代理。

在這個代理對象中,織入性能監(jiān)視的橫切邏輯。

public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) 是CGLib定義的Interceptor接口方法,它攔截所有目標(biāo)類方法中的調(diào)用。

其中

  • obj表述目標(biāo)類的實(shí)例

  • method為目標(biāo)類方法的反射對象

  • args為方法的動態(tài)入?yún)?/font>

  • proxy為代理類的實(shí)例

測試類

通過CglibProxy為ForumSerivceImpl類創(chuàng)建代理對象,并測試代理對象的方法

package com.xgj.aop.base.cglib;public class ForumServiceTest {public static void main(String[] args) {CglibProxy cglibProxy = new CglibProxy();// 通過動態(tài)生成子類的方式創(chuàng)建代理類ForumServiceImpl forumService = (ForumServiceImpl) cglibProxy.getProxy(ForumServiceImpl.class);// 調(diào)用代理類的業(yè)務(wù)方法forumService.removeTopic(1);forumService.removeForum(2);} }

運(yùn)行結(jié)果

通過輸出,可以看到除了兩個業(yè)務(wù)方法中都織入了性能監(jiān)控的邏輯外,還發(fā)現(xiàn)代理類的名字變成了

com.xgj.aop.base.cglib.ForumServiceImpl$$EnhancerByCGLIB$$2088954a

這個特殊的類就是CGLib為ForumServiceImpl動態(tài)創(chuàng)建的子類。

注意:由于cglib采用動態(tài)創(chuàng)建子類的方式生成代理對象,所以不能對目標(biāo)類中的final或者private方法進(jìn)行代理

總結(jié)

以上是生活随笔為你收集整理的Java-CGLib动态代理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。