一. 静态代理

代理类和委托类都实现接口,但是代理类的方法的具体实现是在委托类中实现的,代理类仅仅是调用委托类的方法,并在委托类方法调用之前或者之后或者出现异常时添加一些额外的功能。客户类只需获得一个有代理类实现接口的对象,使用该对象中的方法即可。

二. JDK动态代理
使用方式:
Java在java.lang.reflect.proxy下实现了代理类。
首先委托类实现接口中的方法,然后需要定义一个类MyClass实现了InteceptorHandler接口,该接口中只有一个方法为

    在MyClass类中将invoke方法实现其中的proxy为代理对象实例,method为当前proxy对象被代理的方法,args为被代理方法所需的参数。
创建好该InteceptorHandler的实现类后,接下来需要通过Proxy类下的newProxyInstance方法来创建代理类。 

    Loader为当前目标对象使用的类加载器,获取加载器的方法是固定的。Interfaces 指定当前目标对象实现的接口的类型,使用泛型方式确认类型
    H	指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法,即invoke方法。

动态代理实现的原理:
通过newProxyInstance方法创建一个代理类的字节码文件,并由jvm运行该文件创建一个代理类的对象并返回。可以通过将saveGeneratedFiles属性设置为true来获取该class文        件。
生成代理类的特性:
继承了Proxy类,实现了代理的接口,由于java不能多继承,这里已经继承了Proxy类了,不能再继承其他的类,所以JDK的动态代理不支持对实现类的代理,只支持接口的代理。
提供了一个使用InvocationHandler作为参数的构造方法。
生成静态代码块来初始化接口中方法的Method对象,以及Object类的equals、hashCode、toString方法。
重写了Object类的equals、hashCode、toString,它们都只是简单的调用了InvocationHandler的invoke方法,即可以对其进行特殊的操作,也就是说JDK的动态代理还可以代理上        述三个方法。
代理类实现代理接口的sayHello方法中,只是简单的调用了InvocationHandler的invoke方法,我们可以在invoke方法中进行一些特殊操作,甚至不调用实现的方法,直接返回。
简单来说就是先生成新的class文件,然后加载到jvm中,然后使用反射,先用class取得他的构造方法,然后使用构造方法反射得到他的一个实例。

三. CGLIB动态代理
CGLIB介绍:
开源项目,强大的、高性能以及高质量的Code生成类库。它可以在运行期间扩展java类与实现java接口。
代理实现过程:
首先需要一个待实现的接口MyInterface,在该接口中定义一系列的方法,然后类Subject实现了该接口,接着需要实现MethodInteceptor接口,类名为MyClass,在该实现类中实现intercept方法,

Sub:生成的代理对象
Method:被代理的对象方法
Objects:被代理的对象方法中的参数
methodProxy:代理方法
通过CGLIB动态代理获取代理对象的过程如下:

CGLIB和JDK动态代理的对比:
    1.	JDK动态代理只能针对接口,不能代理类,因为JDK生成的代理类是继承自Proxy类的,而Java是不能支持多继承的,所以对于类,代理类无法继承,也就无法生成该类的代理类
    2.	CGLIB是针对类代理的实现,通过对代理的类生成一个子类,覆盖其中的方法,由于是继承,所以类和方法最好别声明为final类型
    3.	JDK动态代理不需要依赖于第三方类库,而CGLIB需要,但是它需要类来实现任何接口代理的是指定的类生成一个子类。
posted on 2019-09-17 10:15  XYXYH  阅读(157)  评论(0编辑  收藏  举报