Java基礎(chǔ)之動(dòng)態(tài)代理Cglib詳解
一、前言
經(jīng)測試,jdk創(chuàng)建對象的速度遠(yuǎn)大于cglib,這是由于cglib創(chuàng)建對象時(shí)需要操作字節(jié)碼。cglib執(zhí)行速度略大于jdk,所以比較適合單例模式。另外由于CGLIB的大部分類是直接對Java字節(jié)碼進(jìn)行操作,這樣生成的類會在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 訂單號
* @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è)代理對象
*
* @param clazz 類型
* @return 代理對象
*/
public Object creatProxyedObj(Class<?> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
/**
* 代理方法
*
* @param proxyObject 代理對象
* @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("訂單號錯(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用poi做加自定義注解實(shí)現(xiàn)對象與Excel相互轉(zhuǎn)換
這篇文章主要介紹了Java使用poi做加自定義注解實(shí)現(xiàn)對象與Excel相互轉(zhuǎn)換,對大家的學(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-10
Spring?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è)問題,該如何對字符串進(jìn)行兩個(gè)編碼的轉(zhuǎn)換呢,下面小編給大家分享下java中如何在ISO-8859-1和UTF-8之間相互轉(zhuǎn)換,感興趣的朋友一起看看吧2021-12-12
SpringCloud微服務(wù)網(wǎng)關(guān)限流方式
這篇文章主要介紹了SpringCloud微服務(wù)網(wǎng)關(guān)限流方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例
本篇文章主要介紹了Java中用Socket實(shí)現(xiàn)HTTP文件上傳實(shí)例,詳細(xì)的介紹了通過讀取Socket的輸入流來實(shí)現(xiàn)一個(gè)文件上傳的功能,有興趣的同學(xué)可以一起了解一下2017-04-04
Java使用GZIP壓縮導(dǎo)致HTTP請求返回亂碼問題解決
這篇文章主要為大家介紹了Java壓縮GZIP導(dǎo)致HTTP請求返回亂碼問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
詳解如何用Java實(shí)現(xiàn)對m3u8直播流抽幀
抽幀(frame extraction)是指從視頻流中提取一些特定的幀,通常是關(guān)鍵幀或者隨機(jī)幀,以供后續(xù)處理。這篇文章主要為大家介紹了如何用Java實(shí)現(xiàn)對m3u8直播流抽幀,需要的可以參考一下2023-03-03

