当前位置: 首页 > 面试题库 >

代理不能转换为CLASS

孟光耀
2023-03-14
问题内容

我正在使用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 类的原因

您可以<tx:annotation-driven proxy-target- class="true"/>用来指示Spring使用CGLIB代理,它们是代理类的实际子类,但是我认为最好是针对接口进行编程。如果需要访问代理类中未在其接口之一中声明的某些方法,则应首先问自己,为什么会这样?
(此外,在上面的代码中,中没有引入新的方法UserDao,因此将bean强制转换为这种具体的实现类型毫无意义。)

在Spring官方参考中了解有关不同代理机制的更多信息。



 类似资料: