http://www.iteye.com/topic/323547
大家都知道 AOP 使用了代理模式, 本文主要介绍两个代理模式怎么设置以及区别, 对原文一些内容进行了引用后加入了自己的理解和更深入的阐述:
一, JDK 代理和 CGLIB 代理的底层实现区别
* JDK 代理只能针对实现了接口的类以反射的方式生成代理, 而不能针对类 , 所以也叫 "接口代理"
* CGLIB 是针对类实现代理的, 主要对指定的类以字节码转换的方式 (ASM 框架) 生成一个子类, 并重写其中的方法.
[注意] : 有两种特殊情况, static 与 final 方法:
Final 方法 | Static 方法 | |
Jdk 代理 | 接口无法使用 < span style="font-family: Calibri" ztid="119" ow="24" oh="17">final 关键字,所以不能用。 【报错】 | 接口方法使用了 < span style="font-family: Calibri" ztid="125" ow="30" oh="17">static 后代理对象将无法访问此方法,所以不能用。 【报错】 |
Cglib 代理 | 父类方法使用了 < span style="font-family: Calibri" ztid="135" ow="24" oh="17">final 之后,子类将无法对其进行重写,无法拦截。 【不报错,但不拦截】 | 父类方法使用了 < span style="font-family: Calibri" ztid="141" ow="30" oh="17">static 之后,子类将无法对其进行重写,无法拦截。 【不报错,但不拦截】 |
同时, 当使用 cglib 代理的时候, 目标类一定不能为 final 类(不能被继承), 否则报错.
以上可以看出使用代理的时候, 尽量不要使用 final 和 static 关键字.
二, Spring 中两个模式的调配:
1, 如果目标对象实现了接口, 默认会采用 JDK 的动态代理机制实现 AOP, 但是可以强制使用 CGLIB 实现 AOP ;
2, 如果目标对象没有实现接口, 必须使用 CGLIB 生成代理, spring 会自动在 CGLIB 和 JDK 动态代理之间切换 .
3. 如何强制使用 CGLIB 生成代理?
* 添加 CGLIB 库,<SPRING_HOME>/lib/cglib/*.jar (其实 Spring 的核心包包括了 cglib-nodep-2.2.jar, 或者用 MyEclipse 构建项目也会自动引入)
* 在 spring 的配置文件中加入:
<aop:aspectj-autoproxy proxy-target-class="true"/>
来源: http://www.bubuko.com/infodetail-2582874.html