代码准备
被代理类Teacher
public class Teacher {
public void say() {
System.out.println(String.join(",","I'm a teacher"));
}
}
自定义的MethodInterceptor
CglibProxy和DefaultProxy
//拦截非Object方法
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
Object result=null;
before();
result= proxy.invokeSuper(o,objects);
after();
return result;
}
public Object before(){
System.out.println("before invoke ");
return null;
}
public Object after(){
System.out.println("after invoke");
return null;
}
}
//拦截Object方法
public class DefaultProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if(method.getDeclaringClass()==Object.class){
return methodProxy.invokeSuper(o,objects);
}
return null;
}
}
cglib动态代理使用样列
public class CglibMain {
public static void main(String[] args) throws IOException {
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(Teacher.class);
enhancer.setCallbacks(new Callback[]{new DefaultProxy(),new CglibProxy()});
enhancer.setCallbackFilter(new MethodFilter());
Teacher proxy= (Teacher) enhancer.create();
proxy.say();
}
}
上面是cglib动态代理类的使用步骤,具体的运行是什么,我们需要得到enhancer.create()生成的代理类源码,我们可以通过java的HSDB来查看(https://blog.csdn.net/qq_27378875/article/details/81407989)
---------------------------------分割线--------------------------------------------
cglib动态类源码分析
1、主要生成了下面两个类:
cglib动态生成的Teacher的代理类,可以看出extends了Teacher ,所以我们可以用利用多态强转为Teacher
public class Teacher$$EnhancerByCGLIB$$f312f930 extends Teacher implements Factory
cglib动态生成的FastClass,这个会在第7步骤讲解
public class Teacher$$EnhancerByCGLIB$$f312f930$$FastClassByCGLIB$$41d4d523 extends FastClass
2、
Teacher$$EnhancerByCGLIB$$f312f930的主要参数和方法说明
两个MethodInterceptor是我们自己定义的代理处理类,
private MethodInterceptor CGLIB$CALLBACK_0; //
private MethodInterceptor CGLIB$CALLBACK_1;//我们自己定义的代理处理类,
//这两个属性通过setCallbacks()来赋值
public void setCallbacks(Callback[] var1) {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
this.CGLIB$CALLBACK_1 = (MethodInterceptor)var1[1];
}
我们在main方法里调用了 enhancer.setCallbacks(new Callback[]{new DefaultProxy(),new CglibProxy()});
因此
CGLIB$CALLBACK_0=new DefaultProxy();
CGLIB$CALLBACK_1=new CglibProxy()
Method和MethodProxy(我们现在只分析say()方法,只显示say相关的代码)
private static final Method CGLIB$say$2$Method;//被代理实体类的方法反射类
private static final MethodProxy CGLIB$say$2$Proxy;//cglib的方法代理类,负责的选择调度,每个方法对应一个MethodProxy,后面详细说明
MethodProxy的初始化,很重要
static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
//cglib代理类
Class var0 = Class.forName("com.speedyao.proxy.Teacher$$EnhancerByCGLIB$$f312f930");
//在下一行代码可以看出是Object
Class var1;
Method[] var10000 = ReflectUtils.findMethods(new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$finalize$3$Method = var10000[0];
CGLIB$finalize$3$Proxy = MethodProxy.create(var1, var0, "()V", "finalize", "CGLIB$finalize$3");
var10000 = ReflectUtils.findMethods(new String[]{"getName", "()Ljava/lang/String;", "setName", "(Ljava/lang/String;)V", "say", "()V"}, (var1 =
CGLIB$say$2$Method = var10000[2];//
//这个在下面会用到
CGLIB$say$2$Proxy = MethodProxy.create(var1, var0, "()V", "say", "CGLIB$say$2");
}
MethodProxy.create(var1, var0, "()V", "say", "CGLIB$say$2")的方法代码
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
MethodProxy proxy = new MethodProxy();
proxy.sig1 = new Signature(name1, desc);//say()方法
proxy.sig2 = new Signature(name2, desc);//CGLIB$say$2()方法
proxy.createInfo = new CreateInfo(c1, c2);
return proxy;
}
代理类生成的被代理类相关的方法
say():代理类重写的say方法,当我们用动态代理类执行say()时,执行的就是这段代码
public final void say() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_1;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_1;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$say$2$Method, CGLIB$emptyArgs, CGLIB$say$2$Proxy);
} else {
super.say();
}
}
CGLIB$say$2()方法,父类是Teacher,所以此方法实际执行的是Teacher.say()
final void CGLIB$say$2() {
super.say();
}
3、上面主要参数和方法都罗列完了,接下来开始说明调用细节
Teacher proxy= (Teacher) enhancer.create();
proxy.say();
通过上面的say()代码快,我们知道最终执行的是
var10000.intercept(this, CGLIB$say$2$Method, CGLIB$emptyArgs, CGLIB$say$2$Proxy);
由上面的参数分析我们得知var1000=new CglibProxy(),所以这一步就是执行我们自定义的intercept方法
o:是this,也就是动态代理对象
method:CGLIB$say$2$Method ,也就是Teacher.say()的反射Method类
objects: CGLIB$emptyArgs,空参数
proxy:CGLIB$say$2$Proxy,方法代理类
public Object intercept(Object o, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
Object result=null;
//执行前处理
before();
//执行被代理类的真实方法
result= proxy.invokeSuper(o,objects);
//执行后的处理
after();
return result;
}
7、分析proxy.invokeSuper(o,objects)如何触发Teacher.say()
看看proxy.invokeSuper(o,objects)代码
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
通过代码可以看出最终执行代码是
fci.f2.invoke(fci.i2, obj, args);
这行代码关键的两个对象是fci.f2和fci.i2
查看init()方法
private void init()
{
if (fastClassInfo == null)
{
synchronized (initLock)
{
if (fastClassInfo == null)
{
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1);
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(sig1);
fci.i2 = fci.f2.getIndex(sig2);
fastClassInfo = fci;
createInfo = null;
}
}
}
}
通过init()方法,我们得知
fci.f2=helper(ci, ci.c2);
fci.i2 = fci.f2.getIndex(sig2);
fci.f2实际上根据com.speedyao.proxy.Teacher$$EnhancerByCGLIB$$f312f930动态生成的FastClass
fci.f2是CGLIB$say$2方法的索引位
通过下面代码可知上面的结论
static void CGLIB$STATICHOOK1() {
Class var0 = Class.forName("com.speedyao.proxy.Teacher$$EnhancerByCGLIB$$f312f930");
CGLIB$say$2$Proxy = MethodProxy.create(var1, var0, "()V", "say", "CGLIB$say$2");
}
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
MethodProxy proxy = new MethodProxy();
proxy.sig1 = new Signature(name1, desc);//say()方法
proxy.sig2 = new Signature(name2, desc);//CGLIB$say$2()方法
proxy.createInfo = new CreateInfo(c1, c2);
return proxy;
}
public class Signature {
private String name;
private String desc;
public Signature(String name, String desc) {
// TODO: better error checking
if (name.indexOf('(') >= 0) {
throw new IllegalArgumentException("Name '" + name + "' is invalid");
}
this.name = name;
this.desc = desc;
}
}
//**
接下来我们就需要fci.f2.invoke(fci.i2, obj, args)做了什么,fci.f2类型是FastClass的子类,就是我们上面提到的动态生成的Class
Teacher$$EnhancerByCGLIB$$f312f930$$FastClassByCGLIB$$41d4d523
反编译的源码如下,只列了关键代码
*/
public class Teacher$$EnhancerByCGLIB$$f312f930$$FastClassByCGLIB$$41d4d523 extends FastClass {
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
f312f930 var10000 = (f312f930)var2;
int var10001 = var1;
try {
switch(var10001) {
case 0:
return new Boolean(var10000.equals(var3[0]));
case 13:
var10000.CGLIB$say$2();
return null;
case 19:
var10000.say();
return null;
}
} catch (Throwable var4) {
throw new InvocationTargetException(var4);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
}
通过上面的分析我们得知 var1是CGLIB$say$2的index也就是13,var2是Teacher的代理类对象,
所以实际上执行的代码就是
var10000.CGLIB$say$2();
也就是代理类的CGLIB$say$2方法,如下
final void CGLIB$say$2() {
super.say();
}
因为代理类extends Teacher,所以实际上执行的代码就是Teacher.say()
8、接下来总结下调用步骤
动态代理类
Teacher$$EnhancerByCGLIB$$f312f930.say()->
自定义的方法拦截器
CglibProxy.intercept(this, CGLIB$say$2$Method, CGLIB$emptyArgs, CGLIB$say$2$Proxy)->
方法代理
MethodProxy.invokeSuper(o,objects)->
动态生成的FastClass子类
Teacher$$EnhancerByCGLIB$$f312f930$$FastClassByCGLIB$$41d4d523.invoke(fci.i2, obj, args)->
动态代理类
Teacher$$EnhancerByCGLIB$$f312f930.CGLIB$say$2()->
被代理对象也就是Teacher
super.say();
以上便是cglib动态代理类的执行步骤,有什么疑问留言答复,反编译源码需要的话可以留言