0
点赞
收藏
分享

微信扫一扫

cglib底层源码分析(⼀)

cglib是⼀种动态代理技术,可以针对类来⽣成⼀个代理对象。 ⽐如,我们现有⼀个UserService类:

现在利⽤cglib对UserService类中的test()⽅法进⾏增强:

 在分析底层源码实现之前,我们先来试试,cglib能否代理接⼝,定义⼀个UserInterface接⼝

 然后利⽤cglib来代理⼀个接⼝:

 

也是可以正常运⾏的,那么⽤cglib代理⼀个类和代理⼀个接⼝的底层有什么区别呢?我们继续分析。

我们知道,既然要⽣成⼀个代理对象,那么就肯定需要⼀个代理类,只不过当我们⽤cglib时,这个代理 类是由cglib⽣成的,那么我们能不能看到这个代理类是怎么⽣成的呢?

可以!我们只需要在运⾏时加上:

1 -Dcglib.debugLocation=D:\IdeaProjects\cglib\cglib\target\classes

cglib就会将⽣成的代理类放到上⾯所指定的路径上。那么我们分别来看看cglib代理类和接⼝时所产⽣的 代理类是怎样的。

UserService的代理类,我保留了类中⽐较关键的信息:

 UserInterface的代理类,我保留了类中⽐较关键的信息:

 

可以发现这两种情况所产⽣的类区别不⼤,⽆⾮就是UserService代理类是UserService的⼦类, UserInterface代理类实现了UserInterface。

我们可以发现在代理类中(以上两个任选⼀个),都存在⼀个test()⽅法和CGLIB$test$0()(以 UserService代理类举例⼦):

test()⽅法内会去调⽤所设置的Callbacks中的intercept(),相当于执⾏增强逻辑,如果没有Callbacks, 则会执⾏super.test(),那么我们⾃然能想到,如果不设置Callbacks,那是不是就能正常执⾏呢?⽐如 这样:

 

不好意思,运⾏这段代码时,cglib在构造代理对象时就会报⼀个没有Callbacks的空指针异常,所以我 们⽆法看到我们想看到的效果。

但是这并不影响我们继续研究,我们再来看代理类中的另外⼀个⽅法:

 这个⽅法我们并不能直接调⽤,要通过所设置的Callback,也就是MethodInterceptor中的 MethodProxy对象来调⽤,MethodProxy对象表示⽅法代理,举个例⼦,假如UserService代理对象在 执⾏test()⽅法,那么当执⾏流程进⼊到intercept()⽅法时,MethodProxy对象表示的就是test()⽅法, 但是我们现在知道了在UserService类和UserService代理类中都有test()⽅法,所以MethodProxy对象 代理的就是这两个test(),⽐如:

所以在执⾏methodProxy.invokeSuper()⽅法时,就会去执⾏CGLIB$test$0()⽅法。

我们来总结⼀下cglib的⼤概⼯作原理是:cglib会根据所设置的Superclass,⽣成代理类作为其⼦类, 并且会重写Superclass中的⽅法,Superclass中的某⼀个⽅法,⽐如test(),相应的在代理类中会对应 两个⽅法,⼀个是重写的test(),⽤来执⾏增强逻辑,⼀个是CGLIB$test$0(),会直接调⽤ super.test(),是让MethodProxy对象来⽤的。

 

那接下来的问题就是:

1.代理类是怎么⽣成的?

2. MethodProxy是怎么实现的?

我们下篇⽂章⻅。

举报

相关推荐

0 条评论