Spring 实现AOP有两种方式, JDK动态代理和CGLIB代理,Spring会根据拦截对象来选择何种实现。
如果拦截对象至少实现了一个接口,则会使用JDK动态代理,所有改目标类实现的接口都将被代理。
如果拦截对象没有实现任何接口,则会创建一个CGLIB代理。
关于JDK动态代理和CGLIB实现细节可以看 http://blog.csdn.net/zanglianggo/article/details/46353287
如果你的目标对象实现了接口而有JDK动态代理实现,那么你将得到一个proxy类,这个proxy类是无法转换成目标类的。
package springaop;
import org.springframework.stereotype.Component;
public interface Performance {
void perform();
}
package springaop;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@Component
public class DanceParty implements Performance {//
public void perform() {
// TODO Auto-generated method stub
System.out.println("Dance Party");
//return 0;
}
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DanceAspectConfig.class);
DanceParty dance = (DanceParty)context.getBean("danceParty");
当你从context获取 DanceParty后,强制转换成目标对象时是会报错的,因为JDK实现了一个代理类返回给你。
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy16 cannot be cast to springaop.DanceParty
at springaop.DanceMain.main(DanceMain.java:13)
如果用CGLIB实现,这个强制转换是可以的。你可以强制使用CGLIB来实现Spring的 AOP 在@EnableAspectJAutoProxy(proxyTargetClass=true)
或者在xml里加入 <aop:aspectj-autoproxy proxy-target-class="true"/>
更多的坑和经验详见Spring AOP各种讨论
http://blog.csdn.net/samjustin1/article/details/52382972
http://blog.csdn.net/quzishen/article/details/5803721
http://blog.csdn.net/zanglianggo/article/details/46353287
http://blog.csdn.net/jiankunking/article/details/52143504