步子百科步子百科

鬣狗怎么读音是什么(鬣狗技术)

作者:鬣狗

时间:2021年3月6日

0.cglib介绍

cglib( Byte Code Generation Library)顾名思义字节码生成库。鬣狗cglib本身是读音一款高性能的字节码生成库,我们知道在java中一个类最终都会被编译成字节码文件(class文件),什鬣术然后经过JVM的狗技加载到内存,然后变成可以使用的鬣狗一个类型。顺着这个思路思考下去,读音就可以在运行期(Runtime)拼装生成字节码,什鬣术然后调用ClassLoader相关的狗技方法生成一个类型使用。由于拼装字节码需要了解java的鬣狗汇编指令,这对开发者是读音非常不友好的,cglib提供了高层次的什鬣术API在运行时生成新的java类型,而不用考虑底层具体字节码指令是狗技什么,目前Spring框架、鬣狗以及一些ORM框架也都使用了cglib来在运行期生成新的读音类型。所以了解cglib的什鬣术一些知识有助于理解目前主流框架的思想和源码。

1.代理模式

为什么要说代理模式?目前主流的web开发框架中spring + mybatis中应该经常会听到这些词汇 “什么什么使用了代理模式”;“spring代理使用了cglib”;这里面有两个问题?1. 为什么要使用代理 2.怎么使用的cglib。带着这两个问题继续读这篇文章。

图1 代理模式

如图1展示了一个简单的代理模式,其中涉及到三个对象主体,分别是动作发出者(Actor)、代理(Proxy)、目标对象(Target)。在代理模式中动作的发出者不直接请求目标,而是通过代理去请求目标对象,然后将结果返回,动作发出者直接与代理发生交互。这样的好处就是,在动作发出者和目标之间增加了代理之后,将方法的调用和响应进行了解耦,有了更多的操作空间。比如请求经过代理之后先打印请求参数,然后再去请求目标。

2.Enhancer类创建代理

cglib创建代理类都是从Enhancer类开始的。需要注意的一个点是cglib生成代理的方式是通过继承父类生成子类的方式。

图2 Enhancer创建代理

如图所示,使用Enhancer类创建代理,需要设置父类(setSuperClass)和callbacks。最后调用enhancer.create()方法就生成了一个代理,这个代理继承了Parent类。需要注意的是,callback参数是必须设置的,不然会报错。下面介绍callback作用。

3.Callback介绍

上文将代理模式的时候说到,动作发出者会首先请求代理,然后代理可以先做些事情,然后把请求再转发到目标对象上,这里面"代理做些事情"就是callback。cglib有六种Callback,如图3

图3 Callback

MethodInterceptor

MethodInterceptor顾名思义方法拦截,如图4可以看到在调用parent.running()方法的前后都执行了相应的逻辑。需要格外注意的是:要使用proxy.invokeSuper()方法,不用使用method.invoke(obj,args)这样的调用方式,这样是递归调用代理,还会进入到这个方法。

图4 MethodInterceptor

NoOp

NoOp即No-opeartion,代理层什么都不做,直接把请求转给目标。

LazyLoader

直接看注释,含义是:返回原始方法所在的对象,当代理层的方法被调用的时候这个方法会被调用,但是随后通过代理层请求都会使用第一次返回的这个目标对象。

也就是说,无论请求这通过代理调用目标对象的方法多少次,代理请求的都是有LazyLoader返回的同一个目标对象。

图5 LazyLoader

Dispatcher

功能上与LazyLoader一样,只不过是每次目标方法被调用的时候都会调用这个方法产生一个新的对象。

图6

看完LazyLoader和Dispatcher的功能后有没有联想到什么?对,就是spring的scope,singleton和prototype,即单例和原型,是不是有点像。

InvocationHandler

InvocationHandler功能和JDK代理一样,这里不做多介绍。

FixedValue

目标方法的调用会返回固定值。注意的是FixedValue的loadObject的返回值类型要与调用的目标方法的返回值类型一致。

图7 FixedValue

上面使用Enhancer类设置callback的方式生成的代理类。当通过代理请求目标时,callback会作用于目标对象的所有方法。那么问题来了,如果目标类中有很多方法,想为不同的方法设置不同的Callback怎么办?那就需要CallbackFilter类了。

4.CallbackFilter介绍

图8 CallbackFilter

如图,CallbackFilter的作用就是维护代理类 method-callback之间的映射。其中有一个实现类叫CallbackHelper。

图9 CallbackHelper

CallbackHelper维护一个method到callback之间的映射,其中构造函数里面的代码就是为每一个方法生成一个callback,然后放到HashMap中,具体为方法生成callback的函数getCallback(Method)留给开发者,开发者根据自己的业务场景重写这个方法即可。

图10 CallbackHelper数据结构

CallbackHelper的数据结构是,methodMap中的key是method对应的callback在callbacks中的index。

5.应用

代理方式以及cglib的应用目的是使调用者(caller)和被调用者(callee)直接的调用关系进行解耦。在目前的流行web框架spring和mybatis中都使用了cglib代理模式。在日常工作中,工程代码可能会接入一些公司的定时任务框架、或者是监控、以及其他工具,如何在不破坏工程代码的情况下优雅的解决,代理模式和cglib可以考虑一下。

6.其它

鬣狗技术社区:健康生活,深度思考,硬核技术,技术交流、答疑

github主页:https://github.com/youngFF

git仓库地址:https://github.com/youngFF/MyHearthStone.git

gitbook地址:https://youngff.github.io/MyHearthStone/

欢迎各位加入鬣狗技术社区,希望能够为您提供有思考、有深度的文章。欢迎加入我们,如果你也有想法在鬣狗技术社区发表文章,头条私聊即可。

求 关注➕转发➕点赞,谢谢各位!您的支持就是我们更新的动力