静态代理与动态代理

静态代理

若代理类在程序运行前就已经存在,那么这种代理方式被称为静态代理,这种情况下的代理类通常都是我们在java代码中定义的。通常情况下,静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类。

优点:

1、可以隐藏为委托类的实现

2、可以实现客户与委托类间的解耦,在不修改委托类代码的情况下能够做一些额外的处理

JDK动态代理

代理类在程序运行时创建的代理方式被称为动态代理。也就是说,在这种情况下,代理类并不是在java代码中定义的,而是在运行时根据我们在java代码中的“指示”动态生成的。相比于静态代理,动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。

动态代理关系由两组静态代理关系(中介类与委托类构成了静态代理关系,在这个关系中,中介类是代理类,委托类就是委托类;代理类与中介类也构成一个静态代理关系,在这个关系中,中介类是委托类,代理类是代理类)组成,这就是动态代理的原理。

1、因为利用JDKProxy生成的代理类实现了接口,所以目标类中所有的方法在代理类中都有

2、生成的代理类的所有的方法都拦截了目标类的所有的方法。而拦截器中invoke方法的内容正好就是代理类的各个方法的组成提

3、利用JDKProxy方式必须有接口的存在

4、invoke方法中的三个参数可以访问目标类的被调用方法的API、被调用方法的参数、被调用方法的返回类型

CGLIB动态代理

1、CGLIB是一个强大的,高性能,高质量的code类库。它可以在运行期扩展java类与实现java接口

2、用CGLIB生成代理类是目标类的子类

3、用CGLIB生成代理类不需要接口

4、用CGLIB生成的代理类重写了父类的各个方法

5、拦截器中的intercept方法内容正好就是代理类中的方法体

 

动态代理之两种代理方式原理区别

1、jdk动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而CGLIB动态代理是利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP

3、如果目标对象没有实现接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间切换

如何强制使用CGLIB实现AOP

添加CGLIB库,在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>

注:proxy-target-class默认为false,即默认为jdk动态代理

动态代理之两种代理方式优缺点比较

1、若目标对象实现了若干接口,Spring使用JDK的java.lang.reflect.Proxy类代理

优点:因为有接口,所以使系统更加松耦合

缺点:为每一个目标类创建接口

2、若目标对象没有实现任何接口,Spring使用CGLIB库生成目标对象的子类

优点:因为代理类与目标类是继承关系,所以不需要有接口的存在

缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好

参考资料:java中代理,静态代理,动态代理以及spring aop代理方式,实现原理统一汇总

        Spring处理时自我调用的一些解决方案及一些实现方式的风险

posted @ 2018-05-10 14:52  莱茵河畔  阅读(156)  评论(0)    收藏  举报