Я просматривал весеннюю документацию IOC и наткнулся на следующий фрагмент кода:
<bean name = "messageBroker,mBroker,MyBroker" class = "com.components.MessageBroker">
<property name = "tokenBluePrint">
<ref parent = "tokenService" />
</property>
</bean>
Согласно документации, родительский атрибут тега «ref» используется для ссылки на родительскую фабрику компонентов для текущей фабрики компонентов, но для установки родителя для фабрики компонентов.
Я пробовал следующий фрагмент кода. Но все же я получаю ошибку.
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: ошибка создания bean-компонента с именем 'messageBroker', определенным в ресурсе пути к классу [applicationContext.xml]: не удается разрешить ссылку на bean-компонент 'tokenService' в родительской фабрике: родительская фабрика недоступна в org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference (BeanDefinitionValueResolver.java:360)
Я что-то упускаю? Пожалуйста, посмотрите.




Я считаю, что проблема в том, что ваш дочерний контекст обновляется до того, как будет установлен родительский контекст.
Вот соответствующие конструкторы из 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);
. . .
@Thinker Рад, что смог помочь.
Да, вы правы, сначала обновлялся дочерний контекст. Ваше предложение сработало. Спасибо. Теперь я понимаю, что делал не так. Я пытался установить родительский контекст после обновления дочерней фабрики bean.