转自:https://www.cnblogs.com/hongcong/p/5806024.html
昨天看了一天的代理方面的知识,刚开始看的时候没看出什么花头来,感觉不实用。一大堆的东西,还不如直接new出来,然后调用方法。后来仔细研究了一下AOP(面向切面)的思想,才发现代理的用处实在太大了。现在很多框架包括Spring等,都用到了代理这方面的知识,什么是代理?引用网上的例子,就是一个人去买房子,可以直接去买房子,如果直接去买房子的话就得准备很多的东西,然后跑很多地方,这时候房产中介就出现了,我们可以把买房子的事交给中介,让中介做我们的代理,这样我们会省力很多,不需要关心房子是怎么买下来的。这里先简单的描述一下三种代理的区别吧
1、静态代理:静态代理中的代理类,需要我们自己写。代码如下:
首先是接口类:
然后是委托类
最后是代理类:
当然,这里我把实现代理的过程写在代理类的main方法中了。从上面的代码中可以看出这个静态代理类,非常的笨。如果你想让这个代理类代理多个类的话,代码会越来越多。所以,这时候我们就需要一个动态的代理类;
2、JDK动态代理类:
JDK动态代理类实现了InvocationHandler接口。在重写的invoke方法中可以看出,JDK动态代理的基础是反射(method.invoke(对象,参数)),还好反射看的比较多,到现在还记得。在这里需要提到的是Proxy.newProxyInstance(),这个方法。字面上的意思是 新建一个代理类的实例,这一点就和静态代理不同了。里面的参数有三个 类加载器、所有的接口,得到InvocationHandler接口的子类实例。这就是JDK动态代理,该代理有以下几种特点:
1、Interface:对于JDK Proxy,业务类是需要一个Interface的,这是一个缺陷;
2、Proxy:Proxy类是动态产生的,这个类在调用Proxy.newProxyInstance()方法之后,产生一个Proxy类的实力。实际上,这个Proxy类也是存在的,不仅仅是类的实例,这个Proxy类可以保存在硬盘上;
3、Method:对于业务委托类的每个方法,现在Proxy类里面都不用静态显示出来
4、InvocationHandler:这个类在业务委托类执行时,会先调用invoke方法。invoke方法在执行想要的代理操作,可以实现对业务方法的再包装。
以上就是JDK动态代理
3、CGLib动态代理:上面的JDK Proxy只能代理实现了接口的类,而不能实现接口的类就不能实现JDK代理。这时候就需要CGLib动态代理类
这里需要注意的是实现MethodIntercetor接口,必须导入cglib-nodep-2.1_3.jar这个包。CGLib是针对类来实现代理的,他的原理是对指定的目标生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。