У меня есть пакет уха, который содержит одну банку с общими объектами и два военных веб-приложения, которые я хотел бы использовать в общей банке. Я настроил конфигурацию для использования широкого контекста приложения через контексты ContextLoaderListener и webapp отдельно для DispatcherServlet.
Настройка моего демонстрационного приложения примерно следующая
-
common.jar
содержит applicationContext.xml и beanRefContext.xml, которые должны быть широким контекстом приложения (уха). Файлы выглядят следующим образом. shared namespace - это место, где расположен общий bean.
ApplicationContext
<beans>
<!-- namespace etc declarations omitted -->
<context:annotation-config />
<context:component-scan base-package="study.spring.multicontext.shared" />
</beans>
beanRefContext.xml
<beans>
<!-- namespace etc declarations omitted -->
<bean id="sharedContext" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>classpath*:applicationContext.xml</value>
</list>
</constructor-arg>
</bean>
</beans>
-
webapp1
иwebapp2
являются Spring приложениями MVC, упакованными как отдельные войны с файлом web.xml, как показано ниже<web-app> <context-param> <param-name>parentContextKey</param-name> <param-value>sharedContext</param-value> </context-param> <context-param> <param-name>locatorFactorySelector</param-name> <param-value>classpath:beanRefContext.xml</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dos</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dos-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dos</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
и xx-servlet.xml, например, для контекста webapp. веб-пространство имен - это место, где расположены контроллеры.
<beans>
<!-- namespace etc declarations omitted -->
<context:component-scan base-package="study.spring.multicontext.web"/>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="suffix" value=".jsp"/>
</bean>
</beans>
-
Общий bean @Autowired обычным образом в классах контроллера
@Autowired MySharedBean mySharedBean
-
пакет уха содержит как войны, так и банку, а структура похожа на
ear | |--common.jar | |--META-INF | |--applicationContext.xml | |--beanRefContext.xml | |--webapp1.war | |--WEB-INF | |--xx-servlet.xml | |--web.xml | |--webapp2.war | |--WEB-INF | |--xx-servlet.xml | |--web.xml
Проблема в том, что все еще будут два экземпляра bean. Один для каждого контроллера /webapp, поскольку в каждой из войн есть только один контроллер. Я попытался перевернуть конфигурацию, но независимо от того, что я делаю, я либо получаю нулевые экземпляры, либо два экземпляра.
Я проверил ссылки с Eclipse MAT из дампа памяти, и на самом деле есть 4 экземпляра, но я думаю, что эти два предназначены для внутреннего использования Spring. Во всяком случае, оттуда ясно видно, что каждый контроллер имеет свой собственный экземпляр.
Я читал множество сообщений в блогах, дискуссионных форумах и т.д., где они говорят, что это должно быть так просто. Некоторые предлагают JNDI, но, как я понял, это возможно без него.
И невозможно объединить войны и объединить банку внутри. Поскольку это может работать для этого демонстрационного приложения, реальный случай жизни, с которым я работаю, не позволяет этого.
Любая помощь по этому вопросу высоко ценится. Спасибо заранее.
Пример SpringSource с 2007 г. для Spring 2.X, который делает то же самое, но с другой конфигурацией. Немного устарел и ищет решение на основе Spring 3.X, как описано в описании награды.