Разделение applicationContext на несколько файлов

Как правильно разделить конфигурацию Spring на несколько файлов xml?

На данный момент у меня есть

  • /WEB-INF/foo-servlet.xml
  • /WEB-INF/foo-service.xml
  • /WEB-INF/foo-persistence.xml

У моего web.xml есть следующее:

<servlet>
    <description>Spring MVC Dispatcher Servlet</description>
    <servlet-name>intrafest</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/foo-*.xml
        </param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            /WEB-INF/foo-*.xml
    </param-value>
</context-param>


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

Актуальные вопросы:

  • Этот подход правильный / лучший ?
  • Мне действительно нужно указывать расположение конфигураций как в разделах DispatcherServlet И, так и в context-paramразделах?

Что мне нужно иметь в виду, чтобы иметь возможность ссылаться на bean-компоненты, определенные в foo-servlet.xml from foo-service.xml ? Это как-то связано с указанием contextConfigLocation в web.xml?

Обновление 1:

Я использую Spring framework 3.0. Насколько я понимаю, мне не нужно импортировать ресурсы следующим образом:

 <import resource="foo-services.xml"/> 

Это правильное предположение?

Ответов (5)

Решение

Я считаю, что следующая установка является самой простой.

Используйте механизм загрузки файла конфигурации по умолчанию DispatcherServlet :

При инициализации DispatcherServlet структура будет искать файл с именем [servlet-name] -servlet.xml в каталоге WEB-INF вашего веб-приложения и создавать определенные там bean-компоненты (переопределяя определения любых bean-компонентов, определенных с помощью то же имя в глобальной области видимости).

В вашем случае просто создайте файл intrafest-servlet.xml в каталоге WEB-INF и не нужно указывать какую- либо конкретную информацию в web.xml .

В intrafest-servlet.xml файле вы можете использовать импорт для создания вашей XML-конфигурации.

<beans>
  <bean id="bean1" class="..."/>
  <bean id="bean2" class="..."/>

  <import resource="foo-services.xml"/>
  <import resource="foo-persistence.xml"/>
</beans>

Обратите внимание, что команда Spring на самом деле предпочитает загружать несколько файлов конфигурации при создании (Web) ApplicationContext. Если вы все еще хотите сделать это таким образом, я думаю, вам не нужно указывать и параметры контекста ( context-param ), и параметры инициализации сервлета ( init-param ). Подойдет один из двух. Вы также можете использовать запятые, чтобы указать несколько местоположений конфигурации.

Майк Нересон написал следующее в своем блоге по адресу:

http://blog.codehangover.com/load-multiple-contexts-into-spring/

Есть несколько способов сделать это.

1. web.xml contextConfigLocation

Ваш первый вариант - загрузить их все в контекст вашего веб-приложения через элемент ContextConfigLocation. У вас уже будет здесь ваш основной applicationContext, если вы пишете веб-приложение. Все, что вам нужно сделать, это поставить пробел между объявлением следующего контекста.

  <context-param>
      <param-name> contextConfigLocation </param-name>
      <param-value>
          applicationContext1.xml
          applicationContext2.xml
      </param-value>
  </context-param>

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

Вышеупомянутое использует возврат каретки. В качестве альтернативы вы можете просто поставить пробел.

  <context-param>
      <param-name> contextConfigLocation </param-name>
      <param-value> applicationContext1.xml applicationContext2.xml </param-value>
  </context-param>

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

2. Ресурс импорта applicationContext.xml

Другой вариант - просто добавить ваш основной applicationContext.xml в web.xml, а затем использовать операторы импорта в этом основном контексте.

У applicationContext.xmlвас может быть…

  <!-- hibernate configuration and mappings -->
  <import resource="applicationContext-hibernate.xml"/>

  <!-- ldap -->
  <import resource="applicationContext-ldap.xml"/>

  <!-- aspects -->
  <import resource="applicationContext-aspects.xml"/>

Какую стратегию вам следует использовать?

1. Я всегда предпочитаю загружаться через web.xml .

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

2. Если вы загружаете контексты в non-web application, я бы использовал importресурс.

Я автор контекстов модульных пружин .

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

Ключевыми моментами являются

  • контроль зависимостей между модулями
  • контроль того, какие бобы экспортируются и где они используются
  • уменьшена возможность именования коллизий бобов

Простой пример мог бы выглядеть так:

Файл moduleDefinitions.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />

    <module:module id="serverModule">
        <module:config location="/serverModule.xml" />
    </module:module>

    <module:module id="clientModule">
        <module:config location="/clientModule.xml" />
        <module:requires module="serverModule" />
    </module:module>

</beans>

Файл serverModule.xml :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />

    <bean id="serverSingleton" class="java.math.BigDecimal" scope="singleton">
        <constructor-arg index="0" value="123.45" />
        <meta key="exported" value="true"/>
    </bean>

</beans>

Файл clientModule.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config />

    <module:import id="importedSingleton" sourceModule="serverModule" sourceBean="serverSingleton" />

</beans>

Мы имеем дело с двумя типами контекстов:

1 : корневой контекст (родительский контекст. Обычно включает в себя всю инициализацию jdbc (ORM, Hibernate) и другую конфигурацию, связанную с безопасностью Spring)

2 : индивидуальный контекст сервлета (дочерний контекст. Обычно Dispatcher Servlet Context и инициализирует все bean-компоненты, связанные с spring -mvc (контроллеры, сопоставление URL-адресов и т. Д.)).

Вот пример файла web.xml, который включает несколько файлов контекста приложения.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                            http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>Spring Web Application example</display-name>

    <!-- Configurations for the root application context (parent context) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/jdbc/spring-jdbc.xml <!-- JDBC related context -->
            /WEB-INF/spring/security/spring-security-context.xml <!-- Spring Security related context -->
        </param-value>
    </context-param>

    <!-- Configurations for the DispatcherServlet application context (child context) -->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring/mvc/spring-mvc-servlet.xml
            </param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/admin/*</url-pattern>
    </servlet-mapping>

</web-app>

@eljenso: intrafest-servlet.xml контекст веб-приложения xml будет использоваться, если приложение использует SPRING WEB MVC.

В противном случае конфигурация @kosoant подойдет.

Простой пример, если вы не используете SPRING WEB MVC, но хотите использовать SPRING IOC:

В web.xml:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:application-context.xml</param-value>
</context-param>

Затем ваш application-context.xml будет содержать: <import resource="foo-services.xml"/> эти операторы импорта для загрузки различных файлов контекста приложения и помещения в основной application-context.xml.

Спасибо и надеюсь, что это поможет.