微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

spring aop中的代理模式

spring aop中有两种代理模式,一种是jdk动态代理,另外一种是cglib代理。

jdk动态代理:

    是当需要被代理的类实现了某一个接口,那么此时spring aop会使用jdk动态代理,会再创建一个代理类来实现被代理类实现的接口,此时会在代理类中重写接口中的方法,并将被代理类注入进来,

代理类调用切面,并调用被代理类中需要代理的方法,由于代理类实现的是被代理类的接口,所以只能代理接口中有的方法,而只属于被代理类的方法则不能被代理

 优点:

  1. JDK动态代理是JDK原生的,不需要任何依赖即可使用;
  2. 通过反射机制生成代理类的速度要比cglib操作字节码生成代理类的速度更快;

 缺点:

  1. 如果要使用JDK动态代理,被代理的类必须实现了接口,否则无法代理;
  2. JDK动态代理无法为没有在接口中定义的方法实现代理,假设我们有一个实现了接口的类,我们为它的一个不属于接口中的方法配置了切面,Spring仍然会使用JDK的动态代理,但是由于配置了切面的方法不属于接口,为这个方法配置的切面将不会被织入。
  3. JDK动态代理执行代理方法时,需要通过反射机制进行回调,此时方法执行的效率比较低;

cglib代理:

    则是在字节码层面,当被代理类没有实现某一个接口,那么spring aop则会调用cglib代理,在字节码层面创建一个被代理类的子类,创建的子类与自己手写的子类并无多大区别,此时只需要重写被代理类中的方法就好,因为代理类继承了被代理类,所以可以对被代理类中所有的方法进行代理

优点:

  1. 使用cglib代理的类,不需要实现接口,因为cglib生成的代理类是直接继承自需要被代理的类;
  2. cglib生成的代理类是原来那个类的子类,这就意味着这个代理类可以为原来那个类中,所有能够被子类重写的方法进行代理;
  3. cglib生成的代理类,和我们自己编写并编译的类没有太大区别,对方法调用和直接调用普通类的方式一致,所以cglib执行代理方法的效率要高于JDK的动态代理;

缺点:

  1. 由于cglib的代理类使用的是继承,这也就意味着如果需要被代理的类是一个final类,则无法使用cglib代理;
  2. 由于cglib实现代理方法的方式是重写父类方法,所以无法对final方法,或者private方法进行代理,因为子类无法重写这些方法
  3. cglib生成代理类的方式是通过操作字节码,这种方式生成代理类的速度要比JDK通过反射生成代理类的速度更慢

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐