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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

CGLIB 实现代理对象API

發布時間:2023/12/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CGLIB 实现代理对象API 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自?CGLIB 實現代理對象API


1. 加入庫cglib庫
cglib-2.2.jar
asm庫(cglib 需要asm庫,如果沒有加入asm的jar文件,就會報asm錯誤)
asm-3.1.jar
?2. 定義CGLIB操作類
package com.machome.cglibtest;

import java.lang.reflect.Method;
import com.machome.model.StuService;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGlibProxyFactory implements MethodInterceptor {
??? private Object targetObject;

???
??? public Object createProxyInstance(Object targetObject){
??? ?? this.targetObject = targetObject;??? //傳入用戶類
??? ??
??? ?? Enhancer enhancer = new Enhancer();????????? //Enhancer是cglib的核心類
??? ??
??? ???? // 將用戶類設為 Enhancer對象的superclass屬性,,即設為 Enhancer對象的父類
??? ?? enhancer.setSuperclass(this.targetObject.getClass());?????
??? ???? // 設 Enhancer對象的Callbacks屬性,要求必須是Callback接口類型
??? ?? enhancer.setCallback(this);
??? ??
??? ?? return enhancer.create();? //生成代理對象
??? }
???
???
??? @Override
??? public Object intercept(Object arg0, Method arg1, Object[] arg2,
??? ??? ??? MethodProxy arg3) throws Throwable {
??? ??? StuService bean = (StuService)this.targetObject;
??? ??? Object result = null;??? ???
??? ??? if(!arg1.getName().equals("save")&&(bean.findAll().size()==0))
??? ??? {? // 如果方法名不是save(即是get,update,delete方法),而同時實例的列表為空,就不執行方法,而是告警
??? ??? ??? System.out.println("list is null,method is stoped");??? ??? ???
??? ??? }else{
??????? //執行代理方法,傳入實例和方法參數
??? ??? result = arg3.invoke(targetObject, arg2);????? ?? ? ? ? ?
??? ??? }
??? ??? return result;?? ???
??? }
}
3.測試代碼測試代碼:
??? ??? CGlibProxyFactory factory = new CGlibProxyFactory();
??? ??? StuService bean = (StuService)factory.createProxyInstance(
??? ??? ??? ??? ??????????? new StuService());
??? ???
??? ??? List<Stu> stuList = bean.findAll();
??? ??? if(stuList!=null){
??? ??? for(Stu temp:stuList)
??? ??? ??? System.out.println(temp.getId()+":"+temp.getName());
??? ??? System.out.println("finished");

執行結果:
list is null,method is stoped??????????? //bean.findAll()下邊的語句都沒執行)


cglib 執行intercept()的原理:
  • 自定義類應該實現MethodInterceptor接口,,覆寫 intercept()方法
public interface MethodInterceptor extends Callback
{
??? public abstract Object intercept(Object obj, Method method, Object aobj[], MethodProxy methodproxy)
??????? throws Throwable;
}
  • Enhancer對象設其Callback對象(實際是Callbacks對象,一個數組,但我們經常只設一個) ???
?enhancer.setCallback(Callback callback);
  • 這樣當Enhancer對象建立代理對象的時候,就會在執行用戶調用的方法前,先執行intercept()方法

常見的兩種不同的實現MethodInterceptor接口的cglib編程
  • 1.自定義類直接實現MethodInterceptor接口,覆寫 intercept()方法
public class CGlibProxyFactory?implements MethodInterceptor?{
??? public Object createProxyInstance(Object targetObject){
??? ? ??? ...
??? ?? enhancer.setCallback(this);
????? ...
???? }
???
??? @Override
??? public Object?intercept(Object arg0, Method arg1, Object[] arg2,
??? ??? ??? MethodProxy arg3) throws Throwable {
??? ??? ??? ...
??? ??? ??? }???
}
  • 2.另一種方式,定義一個內部類,該類實現MethodInterceptor接口,覆寫intercept()方法
public class CGlibProxyFactory1 {

??? public Object createProxyInstance(Object targetObject){
???? ...
???? enhancer.setCallback(new MethodInterceptorImpl());
???? ...
???? }

??? ?? private class MethodInterceptorImpl?implements MethodInterceptor?{

??? ??? @Override
??? ??? public Object?intercept(Object obj, Method method, Object[] aobj,
??? ??? ??? ??? MethodProxy methodproxy) throws Throwable {
??? ??? ??? ??? ...
??? ??? ??? ??? }
?? }
?}?


注意 public Object intercept(Object obj, Method method, Object[] aobj,MethodProxy methodproxy)方法的第一個參數obj有很大問題
intercept方法里的主要動作是執行invoke方法
有兩種執行方法:
法1:將參數obj傳入invokeSuper()方法:
return methodproxy.invokeSuper(obj, aobj);

obj應該是傳入Enhancer 對象的用戶對象
(即上邊enhancer.setSuperclass(this.targetObject.getClass()))
法2:或者將傳入Enhancer對象前的原始用戶對象傳入invoke()方法:
return methodproxy.invoke(targetObject, aobj);

實際工作中發現,參數obj不態好用. 如果你想intercept()方法中調用對象執行一些方法的話,obj會出stackOverflow這樣的異常
如下面的例子:
??? public Object intercept(Object obj, Method method, Object[] aobj,
??? ??? ??? MethodProxy methodproxy) throws Throwable {
??? ??? StuService bean =?(StuService)obj;
??? ??? Object result = null;??? ???
??? ??? if(!method.getName().equals("save")&&(bean.findAll().size()==0))
??? ??? {? // 如果方法名不是save,而實例的列表為空,就不執行方法,而是告警
??? ??? ??? System.out.println("list is null,method is stoped");??? ??? ???
??? ??? }else{
??? ??? result = methodproxy.invokeSuper(obj, aobj);
??? ??? }
??? ??? return result;
? ? }
執行時會出線面的異常:
Exception in thread "main" java.lang.StackOverflowError
改成下面就好了:??? ???
??? public Object intercept(Object obj, Method method, Object[] aobj,
??? ??? ??? MethodProxy methodproxy) throws Throwable {
??? ??? StuService bean =?(StuService)this.targetObject;? //從外部傳入的原始用戶實例
??? ??? Object result = null;??? ???
??? ??? if(!method.getName().equals("save")&&(bean.findAll().size()==0))
??? ??? {? // 如果方法名不是save,而實例的列表為空,就不執行方法,而是告警
??? ??? ??? System.out.println("list is null,method is stoped");??? ??? ???
??? ??? }else{
??? ??? result = methodproxy.invoke(targetObject, aobj);
??? ??? }
??? ??? return result;
}


cglib 在 spring,hibernate中的應用
Hibernate主要是利用cglib生成pojo的子類并override get方法來實現lazy loading機制
Spring則是利用cglib來實現動態代理。

spring,hibernate同時支持proxy類動態代理和cglib,二者的區別
proxy動態代理只能對 實現了接口 的類生成代理,而不能針對類
CGLIB是針對類生成代理,主要是對用戶類生成一個子類

spring 下缺省是支持proxy 動態代理,如何強制使用CGLIB生成代理?
spring 主要在兩個地方使用代理
AOP:
<aop:aspectj-autoproxy?proxy-target-class="true"/>?
Transaction:
<tx:annotation-driven transaction-manager="txManager"?proxy-target-class="true"/>

1. 加入庫cglib庫
cglib-2.2.jar
asm庫(cglib 需要asm庫,如果沒有加入asm的jar文件,就會報asm錯誤)
asm-3.1.jar
?2. 定義CGLIB操作類
package com.machome.cglibtest;

import java.lang.reflect.Method;
import com.machome.model.StuService;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGlibProxyFactory implements MethodInterceptor {
??? private Object targetObject;

???
??? public Object createProxyInstance(Object targetObject){
??? ?? this.targetObject = targetObject;??? //傳入用戶類
??? ??
??? ?? Enhancer enhancer = new Enhancer();????????? //Enhancer是cglib的核心類
??? ??
??? ???? // 將用戶類設為 Enhancer對象的superclass屬性,,即設為 Enhancer對象的父類
??? ?? enhancer.setSuperclass(this.targetObject.getClass());?????
??? ???? // 設 Enhancer對象的Callbacks屬性,要求必須是Callback接口類型
??? ?? enhancer.setCallback(this);
??? ??
??? ?? return enhancer.create();? //生成代理對象
??? }
???
???
??? @Override
??? public Object intercept(Object arg0, Method arg1, Object[] arg2,
??? ??? ??? MethodProxy arg3) throws Throwable {
??? ??? StuService bean = (StuService)this.targetObject;
??? ??? Object result = null;??? ???
??? ??? if(!arg1.getName().equals("save")&&(bean.findAll().size()==0))
??? ??? {? // 如果方法名不是save(即是get,update,delete方法),而同時實例的列表為空,就不執行方法,而是告警
??? ??? ??? System.out.println("list is null,method is stoped");??? ??? ???
??? ??? }else{
??????? //執行代理方法,傳入實例和方法參數
??? ??? result = arg3.invoke(targetObject, arg2);????? ?? ? ? ? ?
??? ??? }
??? ??? return result;?? ???
??? }
}
3.測試代碼測試代碼:
??? ??? CGlibProxyFactory factory = new CGlibProxyFactory();
??? ??? StuService bean = (StuService)factory.createProxyInstance(
??? ??? ??? ??? ??????????? new StuService());
??? ???
??? ??? List<Stu> stuList = bean.findAll();
??? ??? if(stuList!=null){
??? ??? for(Stu temp:stuList)
??? ??? ??? System.out.println(temp.getId()+":"+temp.getName());
??? ??? System.out.println("finished");

執行結果:
list is null,method is stoped??????????? //bean.findAll()下邊的語句都沒執行)


cglib 執行intercept()的原理:
  • 自定義類應該實現MethodInterceptor接口,,覆寫 intercept()方法
public interface MethodInterceptor extends Callback
{
??? public abstract Object intercept(Object obj, Method method, Object aobj[], MethodProxy methodproxy)
??????? throws Throwable;
}
  • Enhancer對象設其Callback對象(實際是Callbacks對象,一個數組,但我們經常只設一個) ???
?enhancer.setCallback(Callback callback);
  • 這樣當Enhancer對象建立代理對象的時候,就會在執行用戶調用的方法前,先執行intercept()方法

常見的兩種不同的實現MethodInterceptor接口的cglib編程
  • 1.自定義類直接實現MethodInterceptor接口,覆寫 intercept()方法
public class CGlibProxyFactory?implements MethodInterceptor?{
??? public Object createProxyInstance(Object targetObject){
??? ? ??? ...
??? ?? enhancer.setCallback(this);
????? ...
???? }
???
??? @Override
??? public Object?intercept(Object arg0, Method arg1, Object[] arg2,
??? ??? ??? MethodProxy arg3) throws Throwable {
??? ??? ??? ...
??? ??? ??? }???
}
  • 2.另一種方式,定義一個內部類,該類實現MethodInterceptor接口,覆寫intercept()方法
public class CGlibProxyFactory1 {

??? public Object createProxyInstance(Object targetObject){
???? ...
???? enhancer.setCallback(new MethodInterceptorImpl());
???? ...
???? }

??? ?? private class MethodInterceptorImpl?implements MethodInterceptor?{

??? ??? @Override
??? ??? public Object?intercept(Object obj, Method method, Object[] aobj,
??? ??? ??? ??? MethodProxy methodproxy) throws Throwable {
??? ??? ??? ??? ...
??? ??? ??? ??? }
?? }
?}?


注意 public Object intercept(Object obj, Method method, Object[] aobj,MethodProxy methodproxy)方法的第一個參數obj有很大問題
intercept方法里的主要動作是執行invoke方法
有兩種執行方法:
法1:將參數obj傳入invokeSuper()方法:
return methodproxy.invokeSuper(obj, aobj);

obj應該是傳入Enhancer 對象的用戶對象
(即上邊enhancer.setSuperclass(this.targetObject.getClass()))
法2:或者將傳入Enhancer對象前的原始用戶對象傳入invoke()方法:
return methodproxy.invoke(targetObject, aobj);

實際工作中發現,參數obj不態好用. 如果你想intercept()方法中調用對象執行一些方法的話,obj會出stackOverflow這樣的異常
如下面的例子:
??? public Object intercept(Object obj, Method method, Object[] aobj,
??? ??? ??? MethodProxy methodproxy) throws Throwable {
??? ??? StuService bean =?(StuService)obj;
??? ??? Object result = null;??? ???
??? ??? if(!method.getName().equals("save")&&(bean.findAll().size()==0))
??? ??? {? // 如果方法名不是save,而實例的列表為空,就不執行方法,而是告警
??? ??? ??? System.out.println("list is null,method is stoped");??? ??? ???
??? ??? }else{
??? ??? result = methodproxy.invokeSuper(obj, aobj);
??? ??? }
??? ??? return result;
? ? }
執行時會出線面的異常:
Exception in thread "main" java.lang.StackOverflowError
改成下面就好了:??? ???
??? public Object intercept(Object obj, Method method, Object[] aobj,
??? ??? ??? MethodProxy methodproxy) throws Throwable {
??? ??? StuService bean =?(StuService)this.targetObject;? //從外部傳入的原始用戶實例
??? ??? Object result = null;??? ???
??? ??? if(!method.getName().equals("save")&&(bean.findAll().size()==0))
??? ??? {? // 如果方法名不是save,而實例的列表為空,就不執行方法,而是告警
??? ??? ??? System.out.println("list is null,method is stoped");??? ??? ???
??? ??? }else{
??? ??? result = methodproxy.invoke(targetObject, aobj);
??? ??? }
??? ??? return result;
}


cglib 在 spring,hibernate中的應用
Hibernate主要是利用cglib生成pojo的子類并override get方法來實現lazy loading機制
Spring則是利用cglib來實現動態代理。

spring,hibernate同時支持proxy類動態代理和cglib,二者的區別
proxy動態代理只能對實現了接口的類生成代理,而不能針對類
CGLIB是針對類生成代理,主要是對用戶類生成一個子類

spring 下缺省是支持proxy 動態代理,如何強制使用CGLIB生成代理?
spring 主要在兩個地方使用代理
AOP:
<aop:aspectj-autoproxy?proxy-target-class="true"/>?
Transaction:
<tx:annotation-driven transaction-manager="txManager"?proxy-target-class="true"/>

總結

以上是生活随笔為你收集整理的CGLIB 实现代理对象API的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 亚洲一区二区三区久久久 | 亚洲成人av免费 | 男人天堂亚洲 | 亚洲天堂男人网 | 欧美熟妇乱码在线一区 | 一级片高清 | 久久亚州| 中国字幕av | 一级黄网 | 日韩午夜高清 | 天天干天天草天天射 | av在线资源播放 | 久久99久久99精品免观看粉嫩 | 欧美一级少妇 | 播播成人网 | 99精品网站| 国产视频在线观看视频 | 日韩一区二区三区四区 | 国产婷婷综合 | 久久精品视频网站 | 长篇高h乱肉辣文 | 欧美s码亚洲码精品m码 | 久操视频在线观看免费 | 美女久久久久久 | 91麻豆精品一区二区三区 | 老司机亚洲精品 | 超碰国产人人 | 在线观看国产亚洲 | 夜夜欢视频 | 日韩在线精品视频 | 国产亚洲av综合人人澡精品 | 欧美日本| 国产欧美视频一区二区三区 | 中国人妖和人妖做爰 | 精品少妇一区二区三区在线观看 | 国产午夜亚洲精品午夜鲁丝片 | 国产一级内谢 | 日韩成人中文字幕 | 日本xxxx在线观看 | 欧美精品18videosex性欧美 | 无码国产精品一区二区免费16 | 黄色在线网站 | 大帝av| 亚洲精品乱码久久久久久麻豆不卡 | 精品嫩模一区二区三区 | 精品无码国产一区二区三区51安 | 欧美性猛交7777777 | 日本在线观看www | 黄色网址哪里有 | 97在线视频免费观看 | 一本av在线 | 偷拍老头老太高潮抽搐 | 欧美成人aa | 成人亚洲国产 | 国产免费又黄又爽又色毛 | 最新中文字幕 | 色吧综合 | 黑人操白妞 | 国产一级片一区 | 久久精品在线 | 好吊色青青草 | 2021久久| 久久久久久久女国产乱让韩 | 久久精品视频在线播放 | 亚洲欧美日韩精品久久 | 黄色av免费在线观看 | 久久久久久久久久久久久国产 | 97操操| 不卡一区二区在线视频 | 日本性爱视频在线观看 | 自拍 偷拍 欧美 | 911成人网 | 日本a区 | 午夜理伦三级理论 | 另类国产| 亚洲一区二区三区四区五区xx | 日本视频色| 超碰av人人| 黑帮大佬和我的365日第二部 | 人av在线| 欧美成人免费网站 | 一二区视频 | av中字在线| 成人毛片在线观看 | 瑟瑟视频免费观看 | 国产情侣自拍小视频 | 中国国语农村大片 | 亚洲综合网址 | 亚洲综人| 久久婷婷综合色 | 你操综合| 天天干天天操天天玩 | 小早川怜子久久精品中文字幕 | 激烈娇喘叫1v1高h糙汉 | 一区二区三区中文字幕 | 性高潮视频在线观看 | 成人午夜影院在线观看 | 日本三级中文字幕在线观看 | 国产一二三四五区 |