mch*_*ler 24 spring hibernate casting
我正在使用Spring专门为使用Hibernate的DAO类连接依赖项,但是我得到了一个令我困惑的异常:
$ Proxy58无法强制转换为UserDao
我的DAO配置如下:
<bean id="userDao" class="com.domain.app.dao.UserDao">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Run Code Online (Sandbox Code Playgroud)
我有一个接口,抽象基类和最终实现如下.
接口:
public interface Dao {
public void save(Object object);
public Object load(long id);
public void delete(Object object);
public void setSessionFactory(SessionFactory sessionFactory);
}
Run Code Online (Sandbox Code Playgroud)
抽象基类:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
执行:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
以下引发了上述异常:
UserDao dao =(UserDao)context.getBean("userDao");
但是,这不会引发异常:
Dao dao =(Dao)context.getBean("userDao");
如果有人可以提供任何有关此例外情况的帮助或指导,我将非常感激.
zag*_*gyi 50
Spring 默认使用JDK动态代理($Proxy58
就是其中之一),只能代理接口.这意味着动态创建的类型$Proxy58
将实现包装/目标类(UserDao
)实现的一个或多个接口,但它不是它的实际子类.这就是为什么你可以将userDao
bean转换为Dao
接口而不是UserDao
类的原因.
您可以使用它<tx:annotation-driven proxy-target-class="true"/>
来指示Spring使用作为代理类的实际子类的CGLIB代理,但我认为对接口进行编程是更好的做法.如果你需要从代理类访问一些未在其中一个接口中声明的方法,你应该首先问自己,为什么会这样?
(另外,在上面的代码中没有引入新的方法UserDao
,所以无论如何都没有必要将bean转换为这个具体的实现类型.)
在官方Spring参考中查看有关不同代理机制的更多信息.
我正在编写单元测试,并且需要能够为某些调用存根DAO.Per This guys post:http: //www.techper.net/2009/06/05/how-to-acess-target-object-behind-a-spring-proxy/ 我用他提供的方法:
@SuppressWarnings({"unchecked"})
protected <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception {
if (AopUtils.isJdkDynamicProxy(proxy)) {
return (T) ((Advised)proxy).getTargetSource().getTarget();
} else {
return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用代理轻松调用它并获取代理后面的对象,并根据需要直接操作其中的对象.