23.3 cglib动态代理
23.3 cglib动态代理
Java SDK动态代理的局限在于,它只能为接口创建代理,返回的代理对象也只能转换到某个接口类型,如果一个类没有接口,或者希望代理非接口中定义的方法,那就没有办法了。有一个第三方的类库cglib(https://github.com/cglib/cglib),可以做到这一点,Spring、Hibernate等都使用该类库。我们看个简单的例子,如代码清单23-5所示。
1 | public class SimpleCGLibDemo { |
RealService表示被代理的类,它没有接口。getProxy()为一个类生成代理对象,这个代理对象可以安全地转换为被代理类的类型,它使用了cglib的Enhancer类。Enhancer类的setSuperclass设置被代理的类,setCallback设置被代理类的public非final方法被调用时的处理类。Enhancer支持多种类型,这里使用的类实现了MethodInterceptor接口,它与Java SDK中的InvocationHandler有点类似,方法名称变成了intercept,多了一个MethodProxy类型的参数。
与前面的InvocationHandler不同,SimpleInterceptor中没有被代理的对象,它通过MethodProxy的invokeSuper方法调用被代理类的方法:
1 | Object result = proxy.invokeSuper(object, args); |
注意,它不能这样调用被代理类的方法:
1 | Object result = method.invoke(object, args); |
object是代理对象,调用这个方法还会调用到SimpleInterceptor的intercept方法,造成死循环。
在main方法中,我们也没有创建被代理的对象,创建的对象直接就是代理对象。
cglib的实现机制与Java SDK不同,它是通过继承实现的,它也是动态创建了一个类,但这个类的父类是被代理的类,代理类重写了父类的所有public非final方法,改为调用Callback中的相关方法,在上例中,调用SimpleInterceptor的intercept方法。