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>

// 运行 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

为解决上述问题,Spring中如何将oneInstanceMethodFactory bean从编译时类型Object向下转换为运行时类型OneInstanceMethodFactory?(修改两个第三方工厂类不是问题的重点。)

@编辑

感谢来自 的提示@Boris Treukhov,最后我发现问题与此无关,type downcast但确实OneStaticMethodFactory#createFactory返回了其他运行时类型,OneInstanceMethodFactory而不是我自己的错字。现在,从硬连线代码迁移到Spring IoC / DI上述代码后,一切都按预期工作。

4

1 回答 1

1

您应该检查'oneInstanceMethodFactory', 确实是一个实例,方法是 通过容器的方法检查OneInstanceMethodFactory使用名称创建的 bean 类型,或者检查调试器中返回的值。"oneInstanceMethodFactory"getBean()createFactory

以我的经验,这个异常非常简单,通常真的没有这样的公共非静态方法。

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

于 2012-11-23T22:49:27.300 回答