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

    今天在做项目的过程中遇到了 Spring 事务代理类型转换问题 ($ProxyXX cannot be cast to 类型 ) ,经过网上收集找到了解决方案,特此分享,忘大家多多指教。  
一、问题的来由:  ( 例子基于 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 类型。
 
   注:由于字数限制,一次不能写完,所以分为两次编写。该文只是描述了问题的由来。请看下文解决方案。

你可能感兴趣的:(spring事务,cglib,休闲,Spring类型转换,Spring代理)