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对象来⽤的。