代理模式的详解(二)---SpringAOP的两种实现代理模式的详细解读

  上一章主要讲述的就是代理模式中的主要的角色,这次就可以放心的说一下springAOP的两种实现代理模式的方式的区别了。

  首先,动态代理,主要涉及的包就是java.lang.reflect包下面的两个类,Proxy和InvocationHandler,其中InvocationHandler是一个接口,可以通过实现该接口来定义横切的逻辑,并且通过反射的机制调用目标类的代码,动态的将横切的逻辑和业务逻辑整合在一起。这是动态代理的优点,但是它也有不足的地方,就是只能为接口创建代理实例,而没有通过接口定义业务方法的类,这就需要使用到Cglib代理了。

  CGLib底层采用的是字节码的技术,全称:Code Generation Library。CgLib可以为一个类创建一个子类,在子类中采用方法拦截的技术拦截所有父类方法的调用并顺势织入横切逻辑。

  也就是说:

  JDK动态代理是面向接口的。

   CGLib动态代理是通过字节码底层继承要代理类来实现(如果被代理类被final关键字所修饰,那么抱歉会失败)。

  使用方面应该注意一些地方:

    如果要被代理的对象是个实现类,那么Spring会使用JDK动态代理来完成操作(Spirng默认采用JDK动态代理实现机制);

    如果要被代理的对象不是个实现类那么,Spring会强制使用CGLib来实现动态代理。

最最重要的来了-----性能方面  

  我们不管是看书还是看文章亦或是我那个上搜索参考答案,可能很多时候,都可以找到如下的回答:
关于两者之间的性能的话,JDK动态代理所创建的代理对象,在以前的JDK版本中,性能并不是很高,虽然在高版本中JDK动态代理对象的性能得到了很大的提升,但是他也并不是适用于所有的场景。主要体现在如下的两个指标中:
  1、CGLib所创建的动态代理对象在实际运行时候的性能要比JDK动态代理高不少,有研究表明,大概要高10倍;
  2、但是CGLib在创建对象的时候所花费的时间却比JDK动态代理要多很多,有研究表明,大概有8倍的差距;
  3、因此,对于singleton的代理对象或者具有实例池的代理,因为无需频繁的创建代理对象,所以比较适合采用CGLib动态代理,反正,则比较适用JDK动态代理。

 

posted @ 2018-10-17 10:53  丶懿  阅读(1338)  评论(0编辑  收藏  举报