2012-11-23 48 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方法。