spring aop中有两种代理模式,一种是jdk动态代理,另外一种是cglib代理。
jdk动态代理:
是当需要被代理的类实现了某一个接口,那么此时spring aop会使用jdk动态代理,会再创建一个代理类来实现被代理类实现的接口,此时会在代理类中重写接口中的方法,并将被代理类注入进来,
代理类调用切面,并调用被代理类中需要代理的方法,由于代理类实现的是被代理类的接口,所以只能代理接口中有的方法,而只属于被代理类的方法则不能被代理
优点:
缺点:
- 如果要使用
JDK
动态代理,被代理的类必须实现了接口,否则无法代理; JDK
动态代理无法为没有在接口中定义的方法实现代理,假设我们有一个实现了接口的类,我们为它的一个不属于接口中的方法配置了切面,Spring
仍然会使用JDK
的动态代理,但是由于配置了切面的方法不属于接口,为这个方法配置的切面将不会被织入。JDK
动态代理执行代理方法时,需要通过反射机制进行回调,此时方法执行的效率比较低;
cglib代理:
则是在字节码层面,当被代理类没有实现某一个接口,那么spring aop则会调用cglib代理,在字节码层面创建一个被代理类的子类,创建的子类与自己手写的子类并无多大区别,此时只需要重写被代理类中的方法就好,因为代理类继承了被代理类,所以可以对被代理类中所有的方法进行代理
优点:
- 使用
cglib
代理的类,不需要实现接口,因为cglib
生成的代理类是直接继承自需要被代理的类; cglib
生成的代理类是原来那个类的子类,这就意味着这个代理类可以为原来那个类中,所有能够被子类重写的方法进行代理;cglib
生成的代理类,和我们自己编写并编译的类没有太大区别,对方法的调用和直接调用普通类的方式一致,所以cglib
执行代理方法的效率要高于JDK
的动态代理;
缺点:
- 由于
cglib
的代理类使用的是继承,这也就意味着如果需要被代理的类是一个final
类,则无法使用cglib
代理; - 由于
cglib
实现代理方法的方式是重写父类的方法,所以无法对final
方法,或者private
方法进行代理,因为子类无法重写这些方法; cglib
生成代理类的方式是通过操作字节码,这种方式生成代理类的速度要比JDK
通过反射生成代理类的速度更慢
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。