Java基礎(chǔ)之動(dòng)態(tài)代理Cglib詳解
一、前言
經(jīng)測(cè)試,jdk創(chuàng)建對(duì)象的速度遠(yuǎn)大于cglib,這是由于cglib創(chuàng)建對(duì)象時(shí)需要操作字節(jié)碼。cglib執(zhí)行速度略大于jdk,所以比較適合單例模式。另外由于CGLIB的大部分類是直接對(duì)Java字節(jié)碼進(jìn)行操作,這樣生成的類會(huì)在Java的永久堆中。如果動(dòng)態(tài)代理操作過多,容易造成永久堆滿,觸發(fā)OutOfMemory異常。spring默認(rèn)使用jdk動(dòng)態(tài)代理,如果類沒有接口,則使用cglib。
二、服務(wù)
package proxy.cglib; /** * @Description: <br/> * 訂單服務(wù) * <p> * <br/> * @Author: Qz1997 * @create 2021/5/1 10:51 */ public class OrderServiceImpl { /** * 下單 * * @param orderNo 訂單號(hào) * @return 結(jié)果 */ public String preOrder(String orderNo) { System.out.println("OrderServiceImpl.preOrder" + orderNo); return "下單成功"; } /** * 下單 * * @return 結(jié)果 */ public String list() { return "list"; } }
三、代理工廠
package proxy.cglib; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.Objects; /** * @Description: <br/> * Cglib 通過繼承的方式 實(shí)習(xí)代理 * final類 和 final 方法 不能代理 * <p> * <br/> * @Author: Qz1997 * @create 2021/5/1 13:24 */ public class CglibProxyFactory implements MethodInterceptor { /** * 創(chuàng)建一個(gè)代理對(duì)象 * * @param clazz 類型 * @return 代理對(duì)象 */ public Object creatProxyedObj(Class<?> clazz) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } /** * 代理方法 * * @param proxyObject 代理對(duì)象 * @param method 方法 * @param args 方法參數(shù) * @param methodProxy 代理方法 * @return * @throws Throwable */ @Override public Object intercept(Object proxyObject, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { // 判斷方法參數(shù) 如果是null || 參數(shù)格式 <= 0 if (Objects.isNull(args) || args.length <= 0) { return methodProxy.invokeSuper(proxyObject, args); } /// // 判斷這個(gè)方法上是否包含某個(gè)注解 // if (method.isAnnotationPresent(Async.class)) { // // ....進(jìn)行一頓增強(qiáng) // // return method.invoke(proxy, arg); // } Parameter[] parameters = method.getParameters(); Parameter parameter = parameters[0]; Class<?> type = parameter.getType(); // 類型為String if (type == String.class) { String orderNo = (String) args[0]; if (Objects.nonNull(orderNo) && orderNo.length() < 10) { throw new RuntimeException("訂單號(hào)錯(cuò)誤"); } } String result = (String) methodProxy.invokeSuper(proxyObject, args); if (Objects.equals(result, "下單成功")) { System.out.println("發(fā)動(dòng)訂單短信"); } return result; } }
四、結(jié)果
到此這篇關(guān)于Java基礎(chǔ)之動(dòng)態(tài)代理Cglib詳解的文章就介紹到這了,更多相關(guān)Java動(dòng)態(tài)代理Cglib內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用poi做加自定義注解實(shí)現(xiàn)對(duì)象與Excel相互轉(zhuǎn)換
這篇文章主要介紹了Java使用poi做加自定義注解實(shí)現(xiàn)對(duì)象與Excel相互轉(zhuǎn)換,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05使用Java找出兩個(gè)List中的重復(fù)元素三種方法
在Java編程中,我們經(jīng)常需要找出兩個(gè)列表(List)中的重復(fù)元素,在本文中,我們將探討三種方法來實(shí)現(xiàn)這一目標(biāo),需要的朋友可以參考下2023-10-10Spring?Security內(nèi)置過濾器的維護(hù)方法
這篇文章主要介紹了Spring?Security的內(nèi)置過濾器是如何維護(hù)的,本文給我們分析一下HttpSecurity維護(hù)過濾器的幾個(gè)方法,需要的朋友可以參考下2022-02-02使用Java將字符串在ISO-8859-1和UTF-8之間相互轉(zhuǎn)換
大家都知道在一些情況下,我們需要特殊的編碼格式,如:UTF-8,但是系統(tǒng)默認(rèn)的編碼為ISO-8859-1,遇到這個(gè)問題,該如何對(duì)字符串進(jìn)行兩個(gè)編碼的轉(zhuǎn)換呢,下面小編給大家分享下java中如何在ISO-8859-1和UTF-8之間相互轉(zhuǎn)換,感興趣的朋友一起看看吧2021-12-12SpringCloud微服務(wù)網(wǎng)關(guān)限流方式
這篇文章主要介紹了SpringCloud微服務(wù)網(wǎng)關(guān)限流方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例
本篇文章主要介紹了Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例,詳細(xì)的介紹了通過讀取Socket的輸入流來實(shí)現(xiàn)一個(gè)文件上傳的功能,有興趣的同學(xué)可以一起了解一下2017-04-04Java使用GZIP壓縮導(dǎo)致HTTP請(qǐng)求返回亂碼問題解決
這篇文章主要為大家介紹了Java壓縮GZIP導(dǎo)致HTTP請(qǐng)求返回亂碼問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06詳解如何用Java實(shí)現(xiàn)對(duì)m3u8直播流抽幀
抽幀(frame extraction)是指從視頻流中提取一些特定的幀,通常是關(guān)鍵幀或者隨機(jī)幀,以供后續(xù)處理。這篇文章主要為大家介紹了如何用Java實(shí)現(xiàn)對(duì)m3u8直播流抽幀,需要的可以參考一下2023-03-03