在使用spring2.0中申明事务或配置切面Aspect的时候,总是报如下的异常:java.lang.ClassCastException: $Proxy0
at com.spring.aop.LogAspectTest.testLogAspect(LogAspectTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
spring配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

<!-- 配置SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>

    <!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<!-- 配置事务的传播特性 -->                      
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 配置一个切面 -->
<aop:config>
<!-- 
配置切入点,指定切入点表达式 
*   : 代表匹配任意的返回类型。 
       一个全称限定的类型名将只会匹配返回给定类型的方法。
       名字模式匹配的是方法名。 你可以使用 * 通配符作为所有或者部分命名模式。
(..): 匹配了一个接受任意数量参数的方法(零或者更多)
      参数模式
    ()   匹配了一个不接受任何参数的方法
    (..) 匹配了一个接受任意数量参数的方法(零或者更多)
    (*)  匹配了一个接受一个任何类型的参数的方法
    (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型。
-->
<aop:pointcut id="service" expression="execution(* com.spring.transaction.service.avow.UserServiceImpl.*(..))"/> <!-- 配置Advice -->
<aop:advisor pointcut-ref="service" advice-ref="txAdvice"/>
</aop:config>

<bean id="logDAO" class="com.spring.transaction.dao.avow.LogDAOImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<bean id="logService" class="com.spring.transaction.service.avow.LogServiceImpl">
<property name="logDAO" ref="logDAO"/>
</bean>

<bean id="userDAO" class="com.spring.transaction.dao.avow.UserDAOImpl">
<property name="logDAO" ref="logDAO"></property>
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<bean id="userService" class="com.spring.transaction.service.avow.UserServiceImpl">
<property name="userDAO"> 
<ref bean="userDAO"/>
</property>
</bean>

</beans> 包的结构如下:
com.spring.transaction.avow;我想对该包下的UserServiceImpl中的所有方法进行事务上的控制,所以在配置pointcut的时候我这样写的:<aop:pointcut id="service" 
              expression="execution(* com.spring.transaction.service.avow.UserServiceImpl.*(..))"/>
然后在DAO层,我并没有显示的进行事务的提交或回滚操作,业务逻辑完全没有问题
我想应该是申明事务这块的配置上出现的问题,请大家帮忙看下上面的异常时怎么回事?

解决方案 »

  1.   

    如果你用的是JDK动态代理,而不是CGLIB代理的话,你是不是把类强制转换为实现类了而不是接口?。
      

  2.   

    问题出现这段代码上, 
    SystemService service=(SystemServiceImpl)beanFactory.getBean("systemService"); Spring AOP默认是用的JDK的动态代理来实现,大家应该都知道,动态代理只能对对实现了接口的Bean才能生成代理,大家可以debug一下beanFactory.getBean("systemService")获得的其实是$proxy0这样一个玩意,它是一个代理对象,它也实现了SystemService 这个接口,它与SystemServiceImpl其实不搭界的,我不知道这样说,大家是否能能够理解我的意思! 代码改成这样 SystemService service=(SystemService)beanFactory.getBean("systemService");就可以了,呵呵,困扰了很多天的问题终于能够得以解决,再次感谢大家!