2012-11-23 80 views
2

//兩個第三方工廠:低迷現狀,彈簧廠豆

public class OneStaticMethodFactory { 
... 
public static Object createFactory(String oneInstanceMethodFactoryClassName) { 
    ... 
} 
} 

public class OneInstanceMethodFactory { 
... 
public OneObject createObject() { 
    ... 
} 
} 

//硬連線代碼:

OneInstanceMethodFactory oneInstanceMethodFactory = 
(OneInstanceMethodFactory) 
    OneStaticMethodFactory.createFactory("pkg.to.OneInstanceMethodFactory"); 

OneObject oneObject = 
oneInstanceMethodFactory.createObject(); 

//嘗試由Spring bean來替換它們:

<bean id="oneInstanceMethodFactory" class="pkg.to.OneStaticMethodFactory" 
factory-method="createFactory"> 
    <constructor-arg value="pkg.to.OneInstanceMethodFactory"> 
    </constructor-arg> 
</bean> 

<bean id="oneObject" factory-bean="oneInstanceMethodFactory" 
factory-method="createObject"> 
</bean> 

// Run Spring IoC:

java.lang.IllegalStateException: Failed to load ApplicationContext 
    ... 
Caused by: org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'oneObject' defined in class path resource [applicationContext.xml]: 
No matching factory method found: factory bean 'oneInstanceMethodFactory'; 
factory method 'createObject()'. 
Check that a method with the specified name and arguments exists and that it is non-static. 
     at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:528) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1015) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) 
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:605) 
     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925) 
     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472) 
     at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:103) 
     at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1) 
     at org.springframework.test.context.support.DelegatingSmartContextLoader.loadContext(DelegatingSmartContextLoader.java:228) 
     at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124) 
     at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148) 
     ... 26 more 

要解決上面的問題,如何downcast oneInstanceMethodFactory bean從編譯時類型Object到運行時類型Spring中的OneInstanceMethodFactory? (這兩個第三方工廠類的修改不會對問題的地步。)

@EDIT

感謝來自@Boris Treukhov的提示,我終於想通了,這個問題已經無關type downcast,但確實OneStaticMethodFactory#createFactory由於我自己的拼寫錯誤而返回了除OneInstanceMethodFactory之外的其他運行時類型。現在,從硬連線代碼遷移到上面的Spring IoC/DI後,所有內容都按預期工作。

+0

您確定createFactory返回OneInstanceMethodFactory實例嗎? –

+0

是的,當我手動連線他們在Java代碼。 – sof

+0

他們沒有實現任何Spring接口? –

回答

1

你應該檢查'oneInstanceMethodFactory',確實是一個OneInstanceMethodFactory情況下,無論是通過檢查什麼豆型與名稱"oneInstanceMethodFactory"通過容器的getBean()方法或通過檢查createFactory在調試器返回的值創建。

以我的經驗來看,這個異常非常簡單,通常沒有這樣的公共非靜態方法。

向下轉換沒有區別,因爲通過反射方法調用方法,該方法將Object實例作爲this參數。 bean的類型由工廠方法返回的值決定,Spring在bean初始化之前不需要知道該類。實際上,oneObject bean取決於oneInstanceMethodFactory,因此後一個bean將在前者完全初始化,並且Spring將能夠調用它的createObject方法。