Downcast Spring Factory Bean

时间:2012-11-23 20:36:54

标签: spring

//两个第三方工厂:

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>

//运行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后,一切都按预期工作。

1 个答案:

答案 0 :(得分:1)

您应该检查'oneInstanceMethodFactory'是否真的是OneInstanceMethodFactory实例,方法是通过容器"oneInstanceMethodFactory"检查名称为getBean()的bean类型是什么方法或检查调试器中createFactory返回的值。

根据我的经验,这个例外非常简单,通常没有这样的公共非静态方法。

向下转换没有区别,因为这些方法是通过反射方法调用的,该方法将Object实例作为this参数。 bean类型由工厂方法返回的值确定,Spring在初始化bean之前不需要知道类。实际上oneObject bean依赖于oneInstanceMethodFactory所以后一个bean将在前者之前完全初始化,而Spring将能够调用它的createObject方法。