Java基礎(chǔ)之動態(tài)代理Cglib詳解
一、前言
經(jīng)測試,jdk創(chuàng)建對象的速度遠大于cglib,這是由于cglib創(chuàng)建對象時需要操作字節(jié)碼。cglib執(zhí)行速度略大于jdk,所以比較適合單例模式。另外由于CGLIB的大部分類是直接對Java字節(jié)碼進行操作,這樣生成的類會在Java的永久堆中。如果動態(tài)代理操作過多,容易造成永久堆滿,觸發(fā)OutOfMemory異常。spring默認使用jdk動態(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 通過繼承的方式 實習(xí)代理
* final類 和 final 方法 不能代理
* <p>
* <br/>
* @Author: Qz1997
* @create 2021/5/1 13:24
*/
public class CglibProxyFactory implements MethodInterceptor {
/**
* 創(chuàng)建一個代理對象
*
* @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);
}
/// // 判斷這個方法上是否包含某個注解
// if (method.isAnnotationPresent(Async.class)) {
// // ....進行一頓增強
// // 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("訂單號錯誤");
}
}
String result = (String) methodProxy.invokeSuper(proxyObject, args);
if (Objects.equals(result, "下單成功")) {
System.out.println("發(fā)動訂單短信");
}
return result;
}
}
四、結(jié)果


到此這篇關(guān)于Java基礎(chǔ)之動態(tài)代理Cglib詳解的文章就介紹到這了,更多相關(guān)Java動態(tài)代理Cglib內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java idea如何根據(jù)請求路徑url自動找到對應(yīng)controller方法插件
這篇文章主要介紹了java idea如何根據(jù)請求路徑url自動找到對應(yīng)controller方法插件,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
通過Java實現(xiàn)中文分詞與文本關(guān)鍵詞提取
這篇文章主要為大家詳細介紹了如何利用Java實現(xiàn)中文分詞以及文本關(guān)鍵詞提取功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)2023-06-06
用Java連接sqlserver數(shù)據(jù)庫時候幾個jar包的區(qū)別分析
這篇文章主要介紹了用Java連接sqlserver數(shù)據(jù)庫時候幾個jar包的區(qū)別分析,需要的朋友可以參考下2014-10-10

