Cglib代理
CGLIB和我们的java的动态代理是有区别的,CGLIB是代理的类,而我们的java动态代理是代理的对象
首先我们先说一个"好像"和我们要讲的东西不相干的东西.(其实很重要的,能带你拐一个小的弯.)
首先有两个类,子类和父类,父类和子类有相同的方法,当我们调用父类的时候,执行的是父类还是子类?
不管你知道我不知道,我确定是子类.(如果是字节码的画,谁调用的就是谁的字节码)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
那好现在我们不要看上面的东西,说我们的正题了,开始!!
首先说说给大家一个小的CGLIB的小demo的创建方法;
1:Enhancer eh = new Enhancer();-->创建代理生成对象
2:en.setSuperClass(User.class);-->为这个对象设置父类,这里的User.class可以是任何一个你要代理对象
3:eh.setCallback(callback);-->传入一个实现callback的接口 但要实现intercepet方法
4:eh.create();-->创建代理对象并返回
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
代码有了,那凭什么他就能生成代理对象呢?(理解有限,看后勿喷......)
以下的12对象上面的12
1.>>>做的是创建了一个空壳的class文件(至于他叫什么名字,知道他没有必要,我自己打印过,老长的名字...是内存自动分配的知道他就可以了.你在api也找不到他,废话......
)
格式就是class ******{......}
2>>>.为这个代理对象设置父类,就是我们传入的那个User.class(也许你传入的是别的class)格式就是如同
class xxx extends User {.....}
3>>>.第三步是最麻烦的一步,也是最核心的一步,首先我们要明确一点就是我们对一个类进行代理,就是为了要对他的方法进行包装,那好,我们是不是就应该对我们那个被代理的对象的方法进行操作,然后生成代理方法呢?
现在我们的这个代理class就想一张纸,他们没有方法,所以要把方法放进去,那放谁的呢?就是那个user父类的相匹配的方法,比如add()方法.他把父类的这个方法抽取出为Method方法,然后包装后再次放到这个代理中,这时这个add()方法就是被包装过的方法了,那你又可能问这个method的代理用什么代理的呢?还用问啊?当然是cg了,说的通俗点就是代理中的代理,晕吗 ,不晕就接着看.
4>>>.这个时候我们的把这个代理的身体都已经填充好了.就应该返回,正常使用了,使用就是调用他的方法.
这里调用的时候要注意,下面是三种调用方式;
调用之前我们要说上面的那个接口中的方法intercept(1 Object proxy ,2Method mehtod,3Object[] args,4MethodProxy methodProxy)
这几个参数的意思是
1是我们的代理对象
2是我们的原始方法
3是我们们方法的参数
4是我们的代理方法
.那现在我们调用了啊
第一种(正确)--->就是子类调用子类方法
method.invoke(proxy,args)-->这是调用调用子类的方法
第二种(正确)--->呼应上面的补贴题的那段话
methodproxy.invokeSuper(proxy,args)-->这是代理对象调用父类的方法
第三种(错误,出现无线循环)
methodProxy.invoke(proxy,args)-->这是用代理自己的方法,去掉用子类的方法,
下面对为什么会出现无线循环做解答:
因为第三种是代理方法调用子类的方法,首先这就是错误的,因为他自己就是子类,他没有子类,
但是他会自己给自己创建子类对象,然后到了自己的intercepet()方法中又是自己调用子类方法,他没有,他又会去创建,然后呢,就无限循环.......下去了.然后就溢出了.....贴张图