我正在使用Spring来为专门用于使用Hibernate的DAO类的依赖关系进行接线,但是却遇到了一个让我感到困惑的异常:
$ Proxy58无法转换为UserDao
我的DAO的配置如下:
<bean id="userDao" class="com.domain.app.dao.UserDao"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
我有一个接口,抽象基类和最终实现,如下所示。
接口:
public interface Dao { public void save(Object object); public Object load(long id); public void delete(Object object); public void setSessionFactory(SessionFactory sessionFactory); }
抽象基类:
public abstract class BaseDao implements Dao { private SessionFactory sessionFactory; @Transactional @Override public void save(Object object) { PersistentEntity obj = (PersistentEntity) object; currentSession().saveOrUpdate(obj); } @Transactional @Override public abstract Object load(long id); @Transactional @Override public void delete(Object object) { // TODO: this method! } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Session currentSession() { return sessionFactory.getCurrentSession(); } }
实现方式:
public class UserDao extends BaseDao implements Dao { @Transactional(readOnly=true) @Override public Object load(long id) { Object user = currentSession().get(User.class, id); return user; } }
以下引发上述异常:
UserDao dao =(UserDao)context.getBean(“ userDao”);
但是,这不会引发异常:
刀=(刀)context.getBean(“ userDao”);
如果有人可以提供任何帮助或指导,以说明为什么会发生此异常,我将不胜感激。
Spring 默认使用JDK动态代理($Proxy58是其中之一),它只能代理接口。这意味着动态创建的类型$Proxy58将实现由包装的/目标类(UserDao)实现的一个或多个接口,但它不是其实际的子类。这基本上就是为什么您可以将userDaobean强制转换为Dao 接口 ,而不是强制转换为UserDao 类的原因 。
$Proxy58
UserDao
userDao
Dao
您可以<tx:annotation-driven proxy-target- class="true"/>用来指示Spring使用CGLIB代理,它们是代理类的实际子类,但是我认为最好是针对接口进行编程。如果需要访问代理类中未在其接口之一中声明的某些方法,则应首先问自己,为什么会这样? (此外,在上面的代码中,中没有引入新的方法UserDao,因此将bean强制转换为这种具体的实现类型毫无意义。)
<tx:annotation-driven proxy-target- class="true"/>
在Spring官方参考中了解有关不同代理机制的更多信息。