关于Spring事务代理类型转换问题($ProxyXX cannot be cast to 类型)(一)

    今天在作项目的过程当中遇到了 Spring 事务代理类型转换问题 ($ProxyXX cannot be cast to 类型 ) ,通过网上收集找到了解决方案,特此分享,忘你们多多指教。  
1、问题的来由:  ( 例子基于 S2SH 框架 )
     首先晒晒个人项目包的层次结构:        
--src
-----com.dao.inter 接口包
-----com.dao.base 父类包,实现接口
-----com.dao 子类包,基础父类
-----com.service.inter 接口包
-----com.service.base 父类包,实现接口
-----com.service子类包,基础父类
-----com.service.action父类包,实现接口
-----com.action子类包,基础父类
    在 com.dao.inter 包中有一个 IDAO 接口,以下:
public interface IDAO {   
    public List findByHql(String hql);
}
    在 com.dao.base 包下有一个 BaseDao 类,该类实现了接口 IDAO ,以下:      
public class BaseDao extends HibernateDaoSupport implements IDAO {
    public List findByHql(String hql) {
        return this.getHibernateTemplate().find(hql);
    }
}
    在 com.dao 包下有一个 UserDao 类,该类继承了父类 BaseDao ,以下:
public class UserDao extends BaseDao{
    public User loginValidation(String loginName, String loginPassword) {
        return null;
    }
}
    在 com.service.inter 包下有一个 IService 接口,以下:
public interface IService {
    public List findByHql(String hql);
}
    在 com.service.base 包下有一个 BaseService 类,该类实现了接口 IService ,以下:
public class BaseService implements IService {
    private IDAO dao;
     public IDAO getDao() {
        return dao;
    }
     public void setDao(IDAO dao) {
        this.dao = dao;
    }
     public List findByHql(String hql) {
          return this.getDao().findByHql(hql);
    }
}
    在 com.service 包下有一个 UserService 类,该类继承了父类 BaseService ,以下:
public class UserService extends BaseService {
    public User loginValidation(String loginName, String loginPassword) {
        return ((UserDao) this.getDao()).loginValidation(loginName, loginPassword);
    }
}
     com.action 包和这个差很少的,不用多说了。在 Spring 配置文件中实现对象注入,以下:
<!-- 注入sessionFactory到UserDao类 -->
< bean id ="userDao" class ="com.dao.UserDao" >
    < property name ="sessionFactory" ref ="sessionFactory" > </ property >
</ bean >
<!-- 注入UserDao到UserService类 -->
< bean id ="userService" class ="com.service.UserService" >
    < property name ="dao" ref ="userDao" > </ property >
</ bean >
<!-- 注入UserService到UserAction类 -->
< bean id ="userAction" class ="com.action.UserAction" >
    < property name ="service" ref ="userService" > </ property >
</ bean >
    并在 Spring 中进行了事务配置,以下:
<!-- 配置事务操做 -->
< bean id ="transactionManager" class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
    < property name ="sessionFactory" ref ="sessionFactory" />
</ bean >
< tx:advice id ="txAdvice" transactionmanager ="transactionManager" >
    < tx:attributes >
        < tx:method name ="add*" propagation ="REQUIRED" />
        < tx:method name ="insert*" propagation ="REQUIRED" />
        < tx:method name ="delete*" propagation ="REQUIRED" />
        < tx:method name ="update*" propagation ="REQUIRED" />
        < tx:method name ="find*" read-only ="false" propagation ="SUPPORTS" />
        < tx:method name ="select*" read-only ="false" propagation ="SUPPORTS" />
    </ tx:attributes >
</ tx:advice >
< aop:config >
    < aop:pointcut id ="point" expression ="execution(* com.dao.*.*(..))" />
    < aop:advisor advice-ref ="txAdvice" pointcut-ref ="point" />
</ aop:config >
       我在 com.action.UserAction( 继承了 BaseAction 类, BaseAction 又继承了 ActionSupport ) 实现了 Action 的操做。在 Action 处理后调用 Service 层的业务代理方法, Service 层有调用 Dao 层的数据库操做方法,从而实现一个操做。 ( 这样分层不知是否合理,忘多多指教 )
     问题就出在com.service.UserService类中,以下:
java.lang.ClassCastException: $Proxy56 cannot be cast to com.dao.UserDao at comservice.UserService.loginValidation(UserService.java:27) at com.action.UserAction.login(UserAction.java:26)
    因而想为何会在调用 Dao 层方法时出错,而不是在调用 Service 层方法时出错,结合错误 ( 类型转换错误 ) 我作了测试,修改了 UserService 类的方法,以下:
public User loginValidation(String loginName, String loginPassword) {
    System.out.println( this.getDao());
    System.out.println( this.getDao() instanceof IDAO);
    System.out.println( this.getDao() instanceof BaseDao);
    System.out.println( this.getDao() instanceof UserDao);
     return ((UserDao) this.getDao()).loginValidation(loginName, loginPassword);
}
    输出的结果让我汗颜。以下:
INFO [STDOUT] com.dao.UserDao@1162695
INFO [STDOUT] true
INFO [STDOUT] false
INFO [STDOUT] false
ERROR [[ default]] Servlet.service() for servlet default threw exception java.lang.ClassCastException: $Proxy56 cannot be cast to com.dao.UserDao at com.service.UserService.loginValidation(UserService.java:27) at com.action.UserAction.login(UserAction.java:26)
    this.getDao() 对象输入的明明是 UserDao 类的实例,可是使用 instanceof 运算符判断输出 false ,如今还没搞懂为何 ( 但愿知道的告诉我 ) 。按照常理推断,若是是 UserDao 的实例,后面的都应该输出 ture ,由于 UserDao 继承了 BaseDao ,而 BaseDao 实现了 IDAO ,可是该对象只是属于 IDAO 类型。
 
   注:因为字数限制,一次不能写完,因此分为两次编写。该文只是描述了问题的由来。请看下文解决方案。
相关文章
相关标签/搜索