Spring AOP动态代理异常

aop:config的proxy-target-class导致ClassCastException

在使用spring AOP时,遇到动态代理生成的类无法转换到我们自定义的实现类的异常。

切面配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<bean id="personService" class="com.echemi.pay.aop.PersonService">
<property name="name">
<value>露茜</value>
</property>
</bean>
<!--定义切面 -->
<bean id="personaop" class="com.echemi.pay.aop.PersonAop" />
<aop:config>
<aop:aspect ref="personaop">
<aop:pointcut id="infopoint" expression="execution(* *.info(..))" />
<aop:before pointcut-ref="infopoint" method="before_info" />
<aop:after pointcut-ref="infopoint" method="after_info" />
</aop:aspect>
<aop:aspect ref="personaop">
<aop:pointcut id="getpoint" expression="execution(* *.getName(..))" />
<aop:after pointcut-ref="getpoint" method="after_get" />
</aop:aspect>
</aop:config>
执行代码:
1
2
3
4
5
6
7
8
9
10
11
//实现了Service的PersonService类
public class implements Service{
public void test() {
// TODO Auto-generated method stub
System.out.println("hello");
}
}
//读取配置文件,获取对象PersonService
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonService p = (PersonService)factory.getBean("personService");
错误现象:
1
2
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy12 cannot be cast to com.echemi.pay.aop.PersonService
at com.echemi.pay.aop.TestPersonService.main(TestPersonService.java:34)
定位原因:

​ Spring AOP部分使用JDK动态代理或者CGLIB来为目标对象创建代理。默认情况如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理。所有该目标类型实现的接口都将被代理。 若该目标对象没有实现任何接口,则创建一个CGLIB代理。这就说明了为什么强制类型是PersonService时会出现 ClassCastException异常而强制类型是Service时运行正常,因为Service被JDK代理。如果希望在不改变代码的情况下代理目标对象的所有方法,而不只是实现自接口的方法(强制使用CGLIB代理)需要将的proxy-target-class 属性设为true

解决方案:
1
<aop:config proxy-target-class="true">
参考文章:

http://blog.csdn.net/freewindgo/article/details/52083135

http://www.xuebuyuan.com/993356.html