Иерархия контекста Spring с контекстом веб-приложения

#java #spring #spring-mvc

#java #весна #spring-mvc #spring

Вопрос:

Я имею дело с веб-приложением Spring MVC, которое загружается с помощью DispatcherServlet . Это создает XmlWebApplicationContext , который управляет всем приложением:

 <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
  

Теперь есть некоторые модули, которые следует загружать во время выполнения с помощью ContextSingletonBeanFactoryLocator . Поэтому каждый модуль имеет свой собственный ClasspathXmlApplicationContext . Чтобы модуль мог ссылаться на компоненты из XmlWebApplicationContext , он должен быть присоединен к XmlWebApplicationContext , чтобы сформировать Контекстную иерархию, в которой XmlWebApplicationContext должен играть роль родительского, а ClasspathXmlApplicationContext модуль — роль дочернего контекста. К сожалению, я не могу подключить их с помощью

 <beans>
    <bean id="moduleContext"
        class="org.springframework.context.support.ClassPathXmlApplicationContext">
        <constructor-arg>
            ...
        </constructor-arg>
        <constructor-arg ref="parentContext" />
    </bean>
</beans>
  

потому что я пока не нашел способа дать этому WebApplicationContext название parentContext . Я что-то упустил из виду или есть лучший / более простой способ добиться того же другим способом?

Ответ №1:

Если вы используете аннотации, вы можете сделать это:

 @Inject
private XmlWebApplicationContext context;

@Inject
private List<ClassPathXmlApplicationContext> childs;

@PostConstruct
public void refreshContext() {
    for(ClassPathXmlApplicationContext appContext : childs) {
        appContext.setParent(context);
    }
    context.refresh();
}
  

Вы также можете сделать это без аннотаций, используя интерфейсы InitializingBean и ApplicationContextAware.

Отредактированный: childs автоматически настраивается по типу, поэтому Spring введет все компоненты, которые являются экземпляром ClassPathXmlApplicationContext.

Комментарии:

1. Откуда мне взять childs , если я не знаю их заранее?

2. Я попробовал код, который вы предлагаете. Это работает, но не распространяется на ContextSingletonBeanFactoryLocator . Но это ведет в правильном направлении: правильный путь — не использовать a ContextSingletonBeanFactoryLocator , а вручную загрузить дочерние контексты (с помощью a GenericApplicationContext ) и присоединить их к родительскому контексту в a InitializingBean .