如何在春季IOC中设置当前beanFactory的父级

时间:2018-10-09 17:31:47

标签: java spring inversion-of-control

我正在阅读春季IOC文档,并遇到了以下代码片段:

<bean name="messageBroker,mBroker,MyBroker" class="com.components.MessageBroker">
    <property name="tokenBluePrint">
        <ref parent="tokenService" />
    </property>
</bean>

根据文档,“ ref”标记的parent属性用于引用当前bean工厂的父bean工厂,但用于设置bean工厂的父工厂。

我尝试了以下代码段。但是,仍然出现错误。

    String[] xmlFies=new String[1];
    xmlFies[0]="applicationContext.xml";

    ClassPathXmlApplicationContext parentContext=new    ClassPathXmlApplicationContext("tokenConfiguration.xml");
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlFies);
    context.setParent(parentContext);
    context.getBeanFactory().setParentBeanFactory(parentContext.getBeanFactory());
    context.close();
    parentContext.close();

错误:

原因:org.springframework.beans.factory.BeanCreationException:在类路径资源[applicationContext.xml]中创建名称为“ messageBroker”的bean时出错:无法在父工厂中解析对bean“ tokenService”的引用:否母工厂可用     在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:360)

我想念什么吗?请看看。

1 个答案:

答案 0 :(得分:1)

我认为问题在于,在设置父上下文之前,您的子上下文正在刷新。

以下是ClassPathXmlApplicationContext中的相关构造函数:

// this is the constructor that 'context' is using, and refresh is defaulted to true
public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
    this(configLocations, true, null);
}

// the constructor that both others are calling
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
        throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        // you don't want to refresh until your parent context is set
        refresh();
    }
}

// the constructor I think you should use, it will set the parent first and then refresh
public ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
    this(configLocations, true, parent);
}

我会改用最后一个构造函数,以便在调用refresh()之前设置父上下文。

赞:

String[] xmlFies=new String[1];
xmlFies[0]="applicationContext.xml";

ClassPathXmlApplicationContext parentContext = new ClassPathXmlApplicationContext("tokenConfiguration.xml");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xmlFies, parentContext);
. . .