public interface ITarget {
public void iTest(String username);
}
public class IClazz implements ITarget {
@Override
public void iTest(String username) {
System.out.println("this is username = " + username);
}
}
public class ITargetProxy<T> implements MethodInterceptor {
private T t;
public ITargetProxy (T t){
this.t = t;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("interface before");
// 通过被代理类 IClazz 调用目标方法
Object invoke = method.invoke(t, objects);
System.out.println("interface after");
return invoke;
}
}
public class ITest {
public static void main(String[] args) {
String path = TargetProxy.class.getClassLoader().getResource("").getPath();
System.getProperties().setProperty("cglib.debugLocation",path);
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, path);
IClazz iClazz = new IClazz();
ITargetProxy iTargetProxy = new ITargetProxy(iClazz);
ITarget clazz = getClazz(ITarget.class,iTargetProxy);
clazz.iTest("宋江");
}
public static <T> T getClazz(Class<T> clazz,ITargetProxy iTargetProxy){
//字节码增强的类
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(iTargetProxy);
return (T)enhancer.create();
}
}
方式二
public class TargetClazz {
public String thanksHello(String msg){
System.out.println("i am invoke");
return msg;
};
}
public class TargetProxyV2<T> implements MethodInterceptor {
// 表示被代理的目标类:必须是实例,不可以是类信息
T t;
public TargetProxyV2(T t){
this.t = t;
}
public static void main(String[] args){
// 用反编译工具打开生成的字节码类文件即可
String path = TargetProxyV2.class.getClassLoader().getResource("").getPath();
System.getProperties().setProperty("cglib.debugLocation",path);
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, path);
// 创建被代理目标类的实例
TargetProxyV2 proxy = new TargetProxyV2(new TargetClazz());
TargetClazz clazz = (TargetClazz)proxy.getClazz(TargetClazz.class);
clazz.thanksHello("hahahah");
}
public <T> T getClazz(Class<T> clazz){
//字节码增强的类
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return (T)enhancer.create();
}
/**
*
* @param o 表示代理类 TargetClazz$$EnhancerByCGLIB$$cb3b2d89
* @param method 目标方法
* @param objects 目标方法对应的参数
* @param methodProxy 目标方法的代理方法
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before");
Object invoke = method.invoke(t, objects);//正常
// 调用被代理类中的 CGLIB$thanksHello// Object invoke = methodProxy.invokeSuper(t, objects);//异常 方法
// 调用被代理类中的 thanksHello 方法
// Object invoke = methodProxy.invoke(t, objects);//正常
System
..outprintln("after");return
; invoke}
public
方式三
class TargetProxy <Timplements> MethodInterceptor public {
static void main (String[]) args// 用反编译工具打开生成的字节码类文件即可{
String
= path TargetProxy .class.getClassLoader().getResource("").getPath();System
.getProperties().setProperty("cglib.debugLocation",)path;System
.setProperty(DebuggingClassWriter.,DEBUG_LOCATION_PROPERTY) path;TargetProxy
= proxy new TargetProxy ();TargetClazz
= clazz ( TargetClazz).proxygetClazz(TargetClazz.class);.
clazzthanksHello("hahahah");}
public
< TT> getClazz (Class<T)> clazz//字节码增强的类{
Enhancer
= enhancer new Enhancer ();.
enhancersetSuperclass()clazz;.
enhancersetCallback(this);return
( T).enhancercreate();}
@Override
public
Object intercept (Object, oMethod , methodObject [], objectsMethodProxy ) methodProxythrows Throwable System {
..outprintln("before");// Object invoke = method.invoke(o, objects); //异常
// 调用代理类中 CGLIB$thanksHelloObject 方法
=
. invoke invokeSuper methodProxy(,)o; objects//正常// 调用代理类中 thanksHello 方法// Object invoke = methodProxy.invoke(o, objects);//异常
System
.
.printlnout("after");return;
} invoke}
TargetClazz
EnhancerByCGLIB
备注:通过 “method.invoke” 调用会生成代理类:
// 目标类的代理类$$TargetClazz$$cb3b2d89
通过 “methodProxy.invoke” 调用生成代理类:
EnhancerByCGLIB
// 目标类代理类 对应的 FastClass代理类$$TargetClazz$$cb3b2d89
EnhancerByCGLIB
FastClassByCGLIB$$11$$cb3b2d89$$// 目标类 对应的 FastClass代理类$$TargetClazzee3115
FastClassByCGLIB
92$$TargetClazz$$EnhancerByCGLIB$$cb3b2d89
$$finalbd8292
代理类
代理类 String,其父类为被代理类。重要方法如下:
0 ( CGLIB$thanksHello$String)// 调用父类方法,也即目标方法 paramStringreturn {
super
. thanksHello();paramString}public
final
String thanksHello ( String)if paramString( {
this .==nullCGLIB$CALLBACK_0 ) BIND_CALLBACKS(
CGLIB$this);return(
this .!=nullCGLIB$CALLBACK_0 ) ?( String )this..interceptCGLIB$CALLBACK_0(this,0Method CGLIB$thanksHello$,$newObject
[ ]}, { paramString 0Proxy CGLIB$thanksHello$)$:super . thanksHello();paramString}CGLIB$thanksHellothanksHello
invoke
以上代理类方法 thanksHello
& invokeSuper
其实就是 MethodProxy 代理的方法。其中,CGLIB$thanksHellopublic
调用的是static代理方法,MethodProxy调用的是create代理方法。
( Class , Class,String c1, String c2, String desc) //c1 是被代理类(目标类) c2 代理类 desc表示被代理方法的返回值类型 name1表示被代理方法名thanksHello name2表示代理类中的CGLIB$thanksHelloMethodProxy方法 name1= new name2MethodProxy {
(
) proxy ; . =newSignature(
proxy,sig1 ) ; //被代理方法签名(目标类方法签名),也就是代表 void thanksHello().name1= descnewSignature(
proxy,sig2 ) ; //代理类方法签名,也就是 void CGLIB$thanksHello.()=name2new descCreateInfo(,
proxy)createInfo ; //CreateInfo中表示的是被代理类和代理类中的信息 return;c1} c2privatevoidinit
( proxy)
if
( == null)synchronized {
( )fastClassInfo if (== {
null )initLockCreateInfo {
= ;fastClassInfo // f1代表目标类 f2代理代理类 FastClassInfo= {
new ci FastClassInfo createInfo(
)
; fci . = helper(,.
fci)f1 ; // 生成目标类的 FastClass代理类,也就是TargetClazz$$FastClassByCGLIB$bd8292// 生成目标类代理类 对应的 FastClass代理类,也就是目标类代理类(TargetClazz$$EnhancerByCGLIB$$cb3b2d89)的FastClass代理类 TargetClazz$$EnhancerByCGLIB$$cb3b2d89$$FastClassByCGLIB$ee3115ci. ci=c1helper(,
.
fci)f2 ; // 根据方法签名1从 TargetClazz$$FastClassByCGLIB$bd8292 获取 目标类方法void thanksHello()的下标.ci= ci.c2.getIndex
(
fci)i1 ; fci// 根据方法签名2从 TargetClazz$$EnhancerByCGLIB$$cb3b2d89$$FastClassByCGLIB$ee3115 获取 目标类方法vvoid CGLIB$thanksHello.()的下标f1=..sig1getIndex(
)
fci;i2 = fci;f2=null;sig2}}
fastClassInfo } fci}
createInfo public Objectinvoke
(
Object
,
Object
[ ] )throwsThrowable objinit (); argsFastClassInfo = ; {
return..invoke
( fci . fastClassInfo,
, fci)f1;// 通过下标调用对应的方法}fci根据方法签名获取目标方法的下标。 i1public objint argsgetIndex(Signature
)
FastClass
FastClass中涉及的代理类,其功能主要包括:
- 直接通过目标方法的下标执行具体的方法。(优于反射方式)
TargetClazz$$FastClassByCGLIB$bd8292
public Objectinvoke( paramSignatureint
- ,
Object:
, Object []) paramIntthrows InvocationTargetException paramObjecttry switch() paramArrayOfObjectcase 0 : {
/ {
/ 0paramIntreturn {
( (TargetClazz)) 如果下标为.,则调用
thanksHello ((String)paramObject[0]);case1paramArrayOfObject:returnnewBoolean(
( (TargetClazz
) ) .equals([0]paramObject));caseparamArrayOfObject2:return((TargetClazz
) ).
toString ();caseparamObject3:returnnewInteger(
( (TargetClazz
) ) .hashCode());paramObject}}catch(Throwable)throw
new
InvocationTargetException ( null) throwable; {
} throw newIllegalArgumentException("Cannot find matching method/constructor")
;
} TargetClazz$$EnhancerByCGLIB$$cb3b2d89$$FastClassByCGLIB$ee3115
publicObjectinvoke(int
,
Object:
, Object []) paramIntthrows InvocationTargetException paramObjecttry switch() paramArrayOfObjectcase 0 : {
return {
new BooleanparamInt( {
( (TargetClazz
EnhancerByCGLIB ) ).equals([$$0$$cb3b2d89]paramObject));caseparamArrayOfObject1:return((TargetClazz
EnhancerByCGLIB ))
. toString()$$;$$cb3b2d89caseparamObject2:returnnewInteger(
( (TargetClazz
EnhancerByCGLIB ) ).hashCode()$$)$$cb3b2d89;paramObjectcase3:return((TargetClazz
EnhancerByCGLIB ))
. clone()$$;$$cb3b2d89caseparamObject4:return((TargetClazz
EnhancerByCGLIB ))
. newInstance(($$Callback$$cb3b2d89[paramObject])[0]);case5paramArrayOfObject:return((TargetClazz
EnhancerByCGLIB ))
. newInstance(($$Class$$cb3b2d89[paramObject])[0],(Object[paramArrayOfObject])[1 ],(Callback[paramArrayOfObject])[2 ]);case6paramArrayOfObject:return((TargetClazz
EnhancerByCGLIB ))
. newInstance(($$Callback$$cb3b2d89)paramObject[0]);case7paramArrayOfObject:TargetClazzEnhancerByCGLIB.STATICHOOK1
( );
return$$null$$cb3b2d89;CGLIB$case8:return
( (TargetClazz
EnhancerByCGLIB ))
. 0(($$String$$cb3b2d89)paramObject[0CGLIB$thanksHello$]);case9paramArrayOfObject:returnnewBoolean(
( (TargetClazz
EnhancerByCGLIB ) ).1([$$0$$cb3b2d89]paramObject))CGLIB$equals$;caseparamArrayOfObject10:return((TargetClazz
EnhancerByCGLIB ))
. 2()$$;$$cb3b2d89caseparamObject11:CGLIB$toString$returnnewInteger(
( (TargetClazz
EnhancerByCGLIB ) ).3()$$)$$cb3b2d89;paramObjectcase12CGLIB$hashCode$:return((TargetClazz
EnhancerByCGLIB ))
. 4()$$;$$cb3b2d89caseparamObject13:CGLIB$clone$returnTargetClazzEnhancerByCGLIB.
findMethodProxy ((
Signature )$$[$$cb3b2d890CGLIB$]);case14paramArrayOfObject:return((TargetClazz
EnhancerByCGLIB ))
. thanksHello(($$String$$cb3b2d89)paramObject[0]);case15paramArrayOfObject:((TargetClazzEnhancerByCGLIB
) ).
setCallback(($$($$cb3b2d89NumberparamObject)[0]).intValue(paramArrayOfObject),(Callback)[1]) ;returnnullparamArrayOfObject;case16:(
( TargetClazzEnhancerByCGLIB
) ).
setCallbacks(($$Callback$$cb3b2d89[paramObject])[0]);returnnullparamArrayOfObject;case17:TargetClazz
EnhancerByCGLIB .SET_STATIC_CALLBACKS
( (Callback
[$$]$$cb3b2d89)CGLIB$[0]);returnnullparamArrayOfObject;case18:TargetClazz
EnhancerByCGLIB .SET_THREAD_CALLBACKS
( (Callback
[$$]$$cb3b2d89)CGLIB$[0]);returnnullparamArrayOfObject;case19:return
( (TargetClazz
EnhancerByCGLIB ))
. getCallback(($$($$cb3b2d89NumberparamObject)[0]).intValue(paramArrayOfObject));case20:return((TargetClazz
EnhancerByCGLIB ))
. getCallbacks()$$;$$cb3b2d89}paramObject}catch(Throwable)throw
new
InvocationTargetException ( null) throwable; {
} throw newIllegalArgumentException("Cannot find matching method/constructor")
;
} FastClass
FastClass
FastClass
使用 的原因是其实现方式不是通过反射实现的,而是通过下标 快速在 生成目标类的 代理类 | 代理类的 代理类中找到执行的目标方法。
备注:内容来源 https://www.bilibili.com/video/BV1fF411q7QQ?p=4&spm_id_from=pageDriver
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)