2013-04-16 60 views
21

我使用Spring專門爲使用Hibernate的DAO類佈線的依賴關係,但我收到了我不解的異常:代理不能轉換爲CLASS

$ Proxy58不能轉換到userDAO的

吾道配置如下:

<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」);

然而,這並不拋出異常:

道DAO =(DAO)context.getBean( 「userDAO的」);

如果任何人可以提供任何幫助或指導爲什麼發生這種例外情況,我會非常感激。

+0

[$ Proxy25的可能的重複不能轉換爲我的類春框架](http://stackoverflow.com/questions/5702364/proxy25-cannot-be-cast-to-my-class-spring-framework) – artbristol

回答

43

默認情況下,彈簧使用JDK dynamic proxies$Proxy58就是其中之一),它只能代理接口。這意味着動態創建的類型$Proxy58將實現由包裝/目標類(UserDao)實現的一個或多個接口,但它不會是它的實際子類。這就是爲什麼您可以將userDao bean投入到Dao接口,但不是UserDao

你可以使用<tx:annotation-driven proxy-target-class="true"/>來指示Spring使用代理類的實際子類的CGLIB代理,但我認爲最好的做法是對接口進行編程。如果您需要訪問代理類中的某些未在其中某個接口中聲明的方法,則應首先問自己,爲什麼會出現這種情況?
(另外,在你的代碼上面有在UserDao沒有引入新的方法,所以,無論如何鑄造豆這個具體的實施類型是沒有意義的。)

查看更多有關不同的代理機制在官方Spring reference

+0

對未來的參考極有幫助。謝謝@ zagyi的洞察力! – mchandler

+1

也有助於理解Guice。 「 –

+6

」......你應該首先問自己,爲什麼會出現這種情況?「 - 一個例子是在單元測試中測試內部方法。我想測試一個特定的實現,而不是接口。 無論如何,很好的答案! – Zeemee

4

我正在編寫單元測試,需要能夠爲某些調用刷出DAO。 每此人發帖: 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 
    } 
} 

然後你就可以輕鬆地與代理打電話,並得到背後的代理對象,並根據需要在其直接操縱的對象。

相關問題