Skip to main content

动态代理

说一说你理解的代理模式?

代理模式本质上就是一种设计模式,有点类似于这种现实中老板和秘书的角色关系,老板要见客户,老板要开会,但是见客户要订机票订酒店吧,开会,要提前打印材料吧,所以我们可以让秘书干这些事情,具体到这种代码中的话,就是我们常说的这种切面编程AOP的思想,其底层就是用的这种代理模式,比如说我们所有的方法都要进行日志的记录,不可能在每一个方法中的最后和最前面的部分都加上重复的代码吧,所以就用AOP来实现。

代理模式总体上分为两种,一种是静态代理,一种是动态代理,静态代理,需要实现接口,接口实现类,接口的代理类,三者缺一不可,要自己提前实现了,并且如果接口有增加,实现类和代理实现类都要进行同步的编写和增加,我们会在代理类中进行我们的个性化逻辑,比如日志记录,接口耗时记录等等,然后会通过反射去调用我们的这个实现类实现具体的逻辑。这种方式的特点就是,全都要自己实现,不同的接口要有不同的代理类,写完后,打包后,会以字节码的形式生产.class文件。可以看出是比较繁琐的,用的也比较少。于是就有了第二种代理模式,也就是这个动态代理,动态代理总的来说,不需要你去手动编写每一个代理类了,系统会自动帮你生成,极大解放了生产力,具体来说,这个动态代理又分为两种模式,JDK动态代理和CGlib动态代理,JDK动态代理的核心主要是这个InnovationHandler和这个Proxy类,这个Proxy可以根据你的接口和接口实现类去自动生成这种代理类,然后这个代理类回去调用InnovationHandler的这个Invoke方法去进行增强,这个Invoke方法就是我们需要去进行重写来自定义的,最后再通过这个Invoke方法去最终调用我们的实现类来去实现逻辑。总结来说,这个JDK动态代理类,是需要你有实现的接口和实现类的,最后通过动态生产一个代理类实现那个接口来实现动态的逻辑。第二个就是CGlib,CGLib的核心就是MethordIntercepter接口和Enhance类,这个Enhance会通过继承父类的方法来取生产一个代理类,最终调用这个MethordIntercepter的Intercept方法来去进行增强,同样这个Intercept这种方法需要被我们重写。总的来说这个CGLib是是通过继承的这种方式来实现的动态代理,摒弃不要求必须去实现接口。

关于二者的区别,第一个就是实现方式的不同,这个CGLib灵活性更高吗。第二个就是性能,在1.7之前,JDK动态代理效率低一些,因为要通过反射创建类,底层比较慢,后来反射的技术不断优化,性能慢慢和CGLib持平甚至超过了。第三个就是代理的区别,JDK动态代理,只会去代理一次,使用不当有可能有这个AOP代理失效的情况,但是这个CGLib不存在这种情况,因为他是通过继承来实现的,每个方法都已经去重写了父类了。