ClassPathXmlApplicationContext, созданный из нескольких файлов конфигурации, переопределяет bean-компоненты с одинаковыми типами и разными идентификаторами.

У меня есть несколько XML-файлов конфигурации spring, которые используются для создания одного глобального контекста, например:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean class="org.springframework.context.support.ClassPathXmlApplicationContext" id="global.context">
    <constructor-arg index="0">
      <list>
        <value>classpath:config/common/main-springconfig.xml</value>
        <value>classpath:config/me/main-springconfig.xml</value>
      </list>
    </constructor-arg>
  </bean>
</beans>

Я создаю контекст следующим образом:

private static final String springContext = "global.context";
private static final String beanRefContext = "classpath*:global-config.xml";
private ConfigurableApplicationContext springApplicationContext;

ClassPathXmlServiceLocator()
{
    BeanFactoryLocator beanFactoryLocator = ContextSingletonBeanFactoryLocator.getInstance(beanRefContext);
    springApplicationContext = (ConfigurableApplicationContext) beanFactoryLocator.
            useBeanFactory(springContext).getFactory();
}

Проблема в том, что каждая конфигурация имеет определение bean-компонента с одним и тем же типом: some.package.BeanType, но когда контекст полностью создан, доступен только один bean-компонент этого типа.

В javadoc ClassPathXmlApplicationContext есть примечание:

В случае нескольких местоположений конфигурации более поздние определения bean-компонентов будут переопределять определения, определенные в ранее загруженных файлах. Это можно использовать для намеренного переопределения определенных определений bean-компонентов с помощью дополнительного XML-файла.

Но означает ли это, что даже bean-компоненты с разными идентификаторами, определенными в отдельных файлах конфигурации, будут переопределены? Как я могу решить эту проблему?


person thereisnospoon    schedule 28.10.2014    source источник
comment
Их следует переопределять только в том случае, если идентификаторы или имена совпадают, иначе это должно привести к двум разным bean-компонентам. Как проверить, переопределен ли bean-компонент?   -  person M. Deinum    schedule 28.10.2014
comment
Я извлекаю bean-компонент из контекста по идентификатору. Также есть еще один bean-компонент, который вводится bean-компонентом some.package.BeanType. Внедренный bean-компонент неверен, несмотря на аннотацию @Named, которая указывает правильный bean-компонент. Когда я использую только один подфайл конфигурации с необходимым для этой инъекции bean-компонентом, все в порядке.   -  person thereisnospoon    schedule 28.10.2014
comment
@Named не для этого, @Qualifier есть.   -  person M. Deinum    schedule 28.10.2014
comment
Но согласно docs.spring.io/spring/docs/current/spring-framework-reference/ Named эквивалентен Qualifier   -  person thereisnospoon    schedule 28.10.2014
comment
Хм, обычно вы используете @Named для создания компонента @Qualifier (есть 2, кстати!) чтобы отметить конкретный экземпляр.   -  person M. Deinum    schedule 28.10.2014
comment
Исключение произойдет только в том случае, если есть bean-компонент с тем же идентификатором/именем. Если у вас есть bean-компонент без идеи или в XML и вы выполняете сканирование компонентов, вы можете получить несколько экземпляров.   -  person M. Deinum    schedule 28.10.2014
comment
Что бы это ни было, согласно stacktrace bean переопределяется, несмотря на разные идентификаторы. Я думаю, что в этом случае проверка выполняется только по типам компонентов, но не по идентификаторам. Оба компонента определены с идентификаторами.   -  person thereisnospoon    schedule 28.10.2014
comment
Добавленное исключение недействительно. Это произошло из-за того, что я дважды пытался загрузить один и тот же файл конфигурации.   -  person thereisnospoon    schedule 28.10.2014


Ответы (1)


Наконец-то я нашел корень проблемы. Весна работала правильно все время. Проблема была в стороннем классе (так называемом: some.package.BeanType).

person thereisnospoon    schedule 28.10.2014
comment
Вы можете принять свой ответ, поставив галочку, которая удаляет его из списка вопросов без ответов. - person Brian Tompsett - 汤莱恩; 02.06.2015