一、代理概念的理解
1、什么是代理?
其实我的理解其实很简单,就是本来是A做的事,B代替/帮助A去干那个事,这就是代理,B是A的代理,B就叫代理类,A就叫委托类。
这种例子其实在我们的生活中很常见,我们经常看的电视剧中,打官司的电视剧中经常能听到,律师说我的委托人xxx,我是xxx的代理律师,也就是xxx是要打官司,但是它又不懂打官司,所以请了一个人帮他打官司,这种就是代理。
2、什么是静态代理?
个人觉得从代理这件事而言,是不分所谓的静态代理与动态代理的。而在编程语言中有此叫法,主要是因为“能否自动创建这个代理类”的问题。
静态代理就是每次都要手动编写这个代理类。
3、什么是动态代理?
结合上面的静态代理的分析,可以理解动态代理就是不要手动编写代理类,我们可以通过一套方案去实现这个代理类,也就是这个代理类只存在内存中,不会落地到磁盘中。
二、实现
1、静态代理
注意:静态代理的实现有两种方式,一种是“组合”、另一种是“继承”(都是相对于“委托类”而言)。代码我就不写了,只画了UML图。
为什么在代理模式中药采用一个接口?
1、在正常的情况下是不需要有一个接口,由于我们是面向接口编程。另外一个提出一个接口,
这样可以让代理类实现这个接口,也就是代理类中的方法的方法名与RealSubject业务类的方法
名,这样的话,可以调用方,由于代理类与RealSubject方法是一致的,可以让调用方无感知的调用。
2、那为什么不采用不要接口,直接继承委托类的方式呢,然后代理类是重新全部的方法即可。我的理解这个其实是Java语法的问题,在Java中不能多继承,不像C++可以多继承。因为一个代理类可以代理多个委托类。(这里不是说多继承是好的,我只是强调Java没有这种语法,所以不能这么实现)。
3、另外在实现动态代理的时候,充分说明了抽象接口的好处了。
2、动态代理
1)、接口
2)、委托类
3)、动态代理的回调接口类
4)、客户端
三、动态代理类落地到磁盘
由于我们的动态代理对象是在运行时内存中直接创建的对象。在内存中,我们要不到生成的代理对象是怎么样的,在这个类中,我们获取代理对象的字节码文件,然后落地到磁盘,然后反编译打开文件,看看动态代理生成的代理类是什么样的。
反编译代码如下:
从代码中可以看出,通过实现IUserService接口,通过反射实现调用。上面就是JDK动态代理的实现方式,在很多开源的软件中,一般会使用CGLIB做动态代理,像Hibernate、Mybatis等等都是采用它做动态代理,通过继承委托类,生成子类的方式实现。