Совместное использование контекста приложения между двумя WAR? - PullRequest
11 голосов
/ 22 марта 2011

Есть ли способ разделить контекст приложения между двумя развернутыми войнами?Одна война должна подключиться к услугам другой, и я не знаю, с чего начать.

Ответы [ 7 ]

12 голосов
/ 17 марта 2015

У нашей команды было то же самое требование - разделять компоненты Spring между несколькими WAR-ами в Tomcat, и, честно говоря, такие ответы, как «Не делай этого», бесполезны.

Требование вытекает из того факта, что у нас есть приложение с несколькими WAR, работающее на Tomcat, и все WAR нуждаются в доступе к одной и той же СУБД для сохранения информации.Мы используем Spring и Hibernate для доступа к RDBM, и все WAR используют одну и ту же схему и в идеале могут использовать одни и те же Hibernate SessionFactory и Spring Manager manager.

Ответ о том, как это сделать, был размещен здесь:

StackOverflow: общий доступ к ApplicationContext в EAR

и для подведения итогов выполните следующие действия:ваш web.xml:

<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:yourWarSpecificAppContext.xml</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

, где beanRefContext.xml содержит:

<beans>
  <bean id="sharedContext" class="org.springframework.context.support.ClassPathXmlApplicationContext">
    <constructor-arg>
      <list>
        <value>classpath:yourSharedAppContext.xml</value>
      </list>
    </constructor-arg>
  </bean>
</beans>

При этом Spring ContextSingletonBeanFactoryLocator используется для предоставления и совместного использования родительского контекста (в этомслучай, используя имя "sharedContext").Общий контекст будет лениво загружаться, когда первая WAR ссылается на него.

Все компоненты, на которые вы ссылаетесь в общем контексте, должны быть доступны для всех WAR, что означает, что они не могут быть загружены из WEB-INF / classes или WEB-INF / lib в пределах определенной WAR.Они должны быть предоставлены в общий доступ либо с помощью файла EAR, либо путем помещения jar-файлов, содержащих бины (и зависимости), в общую папку «lib» Tomcat ($ CATALINA_HOME / lib), что и сделала наша команда.

Справедливое предупреждение о том, что, если вы используете этот подход, вы, скорее всего, будете располагать большинством своих JAR-файлов в общей папке lib, а не в отдельных веб-приложениях.Для нашего проекта это имело смысл, потому что большинство веб-приложений имеют общий доступ к одним и тем же внутренним службам.

Поскольку хардкорные разработчики Tomcat, скорее всего, будут возражать против размещения большого количества кода в каталоге общей библиотеки Tomcat, я просто перечислю некоторые причины, по которым другие предлагаемые ответы могут не работать.

  • Использование отдельных контекстов приложения для каждой WAR будет означать наличие нескольких пулов соединений с базой данных, по одному для каждой WAR, и отдельную инициализацию дорогостоящего Hibernate SessionFactory для каждой WAR, что увеличивает время запуска сервера и потребление памяти.В более общем смысле, он не позволяет совместно использовать состояние общих серверных служб между веб-приложениями, работающими в том же Tomcat.
  • Помещение персистентного кода в отдельную WAR и использование вызовов REST, по крайней мере, в нашем случае, совершенно неудобно для разработчиков и увеличивает длину пути к базе данных по сравнению с прямыми вызовами общих бинов.
12 голосов
/ 22 марта 2011

Общая цель контейнера веб-приложений, такого как tomcat, состоит в том, чтобы каждое приложение могло работать независимо (так что вы можете останавливать и запускать отдельные приложения, не влияя на другие), что означает, что, вероятно, было приложено много усилий для их разработка специально, чтобы помешать вам сделать это. Поэтому, даже если вы найдете лазейку, я бы рекомендовал не использовать ее, если она не рекомендована или, по крайней мере, не санкционирована проектировщиками.

Я предлагаю вам начать искать другие решения. Например:

  • Вам действительно нужно делиться экземплярами объекта? Если они не имеют состояния, вам может не понадобиться, и вы можете просто запустить копию контекста в каждом приложении.
  • Можете ли вы разделить код, которым вы пытаетесь поделиться, в третью WAR, предоставляющую службу отдыха? Или, может быть, одна из существующих WAR может выступать в качестве службы.
6 голосов
/ 26 мая 2011

Существует информативное сообщение в блоге, которое, я думаю, вам следует проверить: Использование общего родительского контекста приложения в приложении Multi-War Spring

1 голос
/ 22 марта 2011

Возможно, есть способ, если вы запускаете встроенный сервер Jetty и получаете доступ к обоим веб-приложениям из класса, в котором вы запускаете и настраиваете сервер Jetty.

См .:

ВстраиваниеПричал

0 голосов
/ 27 октября 2017

Согласился с @RichardSmith, принятый ответ мне не помог.В то время как ответ Ричарда помог мне направить меня в правильном направлении, я использую Jetty, поэтому не могу использовать EAR.Я закончил тем, что использовал контекст сервера, чтобы разделить объект (ы) между войнами - работает даже с горячими (пере) развернутыми веб-приложениями:

https://stackoverflow.com/a/46968645/1287091

Вероятно, способ приспособить это дляTomcat также.

0 голосов
/ 22 марта 2011

Вы могли бы связать контекст с JNDI, если он не существует.

Цена за это заключается в том, что контекст каждого веб-приложения должен каким-то образом учитывать, что он может быть не основным.

Кроме того, вы должны быть очень осторожны с условиями гонки, например,

  • первый запуск веб-приложения, обнаружение отсутствия контекста
  • первый веб-приложение начинает создавать контекст
  • запускается второе веб-приложение, обнаруживает отсутствие контекста
  • второе веб-приложение начинает создавать контекст
  • первое веб-приложение завершает создание контекста, связывает его
  • второе веб-приложение завершает создание контекста, связывает его
  • поздравляю, вы потеряли все компоненты из контекста первого веб-приложения
0 голосов
/ 22 марта 2011

Вам нужен общий контекст runtime , или вы хотите просто повторно использовать определения bean-компонентов в двух приложениях?

Если это только последнее, то вы могли бы легкоИзвлеките общие XML-файлы контекста Spring в некоторую общую зависимость и просто повторно используйте JAR в двух веб-приложениях.Однако если вам нужно, чтобы компоненты / сервисы в каждом приложении говорили друг с другом, вам нужен другой вариант.

...