Spring: namespace vs contextConfigLocation parametry init w web.xml

Czytam dokumentację Spring MVC i mam pytanie dotyczące init params. Używam Spring 3.2 jeśli to ma znaczenie. Jaka jest różnica między contextConfigLocation a przestrzenią nazw? Czy contextConfigLocation jest przeznaczony tylko do określenia folderów, w których Klasa context może znaleźć definicję XML, a atrybut przestrzeni nazw jest przeznaczony do określenia nazwy pliku?

<servlet>
        <servlet-name>AppServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF</param-value>
        </init-param>
        <init-param>
            <param-name>namespace</param-name>
            <param-value>application-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
Czy to prawda? Powinien używać /WEB-INF / application-context.xml? I czy określić ścieżki?
Author: BalusC, 2013-04-04

3 answers

TL;DR

Po prostu ustaw wartość contextConfigLocation za każdym razem, gdy musisz określić niestandardowe pliki konfiguracyjne. W ten sposób będziesz określać zarówno nazwy plików konfiguracyjnych, jak i ich lokalizacje.

{[7] } jest zasadniczo alternatywnym sposobem informowania klasy kontenera Spring context loader o tym, jakiego pliku konfiguracyjnego użyć. Nigdy nie zawracam sobie tym głowy, ale po prostu używam contextConfigLocation, gdy muszę skonfigurować niestandardowe pliki konfiguracyjne.

Oto przykład z mojej poprzedniej wiosny projekty (niektóre konfiguracje pominięte ze względu na zwięzłość):

www.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
            /WEB-INF/spring/security/spring-security-context.xml
        </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>

Długa odpowiedź

OK, najpierw wyjaśnijmy sobie kilka ważnych chwil. Istnieją dwa rodzaje kontekstów, z którymi mamy do czynienia:]}
  1. root context (parent)
  2. indywidualny kontekst servleta (dziecko)

Cytat z API Spring Framework (wersja 3.2.2 w momencie pisania tego) dla Webaplicationcontext (podkreślenie):

Podobnie jak ogólne konteksty aplikacji, konteksty aplikacji internetowych są hierarchiczne. istnieje pojedynczy kontekst główny dla każdej aplikacji, podczas gdy każdy servlet w aplikacji (w tym Servlet dyspozytora w MVC framework) posiada własny kontekst potomny .

Również tutaj: hierarchie kontekstu :

Na przykład, jeśli tworzysz aplikację webową Spring MVC, możesz Wola zazwyczaj mają root Web Applicationcontext załadowany za pomocą Springa ContextLoaderListener and a child WebApplicationContext loaded via Dyspozytornia sprężyny . Skutkuje to kontekstem rodzic-dziecko hierarchii, w której współdzielone komponenty i konfiguracja infrastruktury są deklarowane w kontekście głównym i używane w kontekście potomnym przez komponenty www.

I tu: 17.2 Dyspozytornia :

Instancje ApplicationContext na wiosnę mogą być skalowane. W Web MVC framework, każdy DispatcherServlet ma własną aplikację Webkontekst, który dziedziczy wszystkie ziarna już zdefiniowane w korzeniu Webaplicationcontext . Te odziedziczone fasolki można przecenić w Servlet-specific scope, i można zdefiniować nowe Scope-specific beans lokalne do danej instancji Servleta.


Teraz zobaczmy konfigurację kontekstu aplikacji root . Proszę. jest przykładem:
www.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">
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/daoContext.xml
            /WEB-INF/spring/applicationContext.xml
        </param-value>
    </context-param>
</web-app>


Z oficjalnej dokumentacji wiosennej (moja):
5.14.4 wygodna instancja ApplicationContext dla aplikacji internetowych :

Instancje ApplicationContext można tworzyć deklaratywnie za pomocą, na przykład ContextLoader. Oczywiście można również tworzyć Instancje ApplicationContext programowo za pomocą jednego z Implementacje ApplicationContext.

Możesz

Zarejestrować ApplicationContext używając contextloaderlistener (zobacz przykład powyżej)

Słuchacz sprawdza parametr contextConfigLocation. jeśli parametr nie istnieje, słuchacz używa / WEB-INF / applicationContext.XML jako domyślny . Gdy parametr exist, słuchacz oddziela ciąg za pomocą predefiniowanych ograniczniki (przecinki, średniki i spacje) i używa wartości jako miejsca, w których zastosowanie konteksty będą przeszukiwane. Ścieżka w stylu mrówki obsługiwane są również wzorce. Przykładami są/WEB-INF / *Context.xml dla wszystkie pliki z nazwami kończącymi się na " Context.xml", mieszczący się w Katalog "WEB-INF" oraz/WEB-INF/**/*.xml, dla wszystkich takich plików w dowolnym podkatalogu "WEB-INF".


Dość często Konfiguracja Spring jest podzielona na wiele plików. Jest to bardziej logiczne i wygodne, szczególnie w dużych projektach. W naszym przykładzie wyraźnie zdefiniowaliśmy dwa konfiguracja plików XML: daoContext.XML I applicationContext.xml w lokalizacji niestandardowej: /WEB-INF/spring/. Ponownie, gdybyśmy nie zdefiniowali contextConfigLocation , ContextLoaderListener spróbowałby zlokalizować domyślny plik konfiguracyjny: /WEB-INF/applicationContext.xml.

Uwaga:
Kontekst główny jest opcjonalny . Zobacz też tę odpowiedź: https://stackoverflow.com/a/7451389/814702

Więc jeśli domyślna /WEB-INF/applicationContext.xml plik konfiguracyjny robi nie odpowiada twoim potrzebom, użyj ContextLoaderListener wraz z <context-param> contextConfigLocation, gdzie można zdefiniować własne pliki konfiguracyjne , aby zdefiniować kontekst głównej aplikacji.


Następnie zobaczmy indywidualny (potomny) kontekst aplikacji . Z oficjalnej dokumentacji wiosennej (moja):
17.2 DispatcherServlet

Po zainicjowaniu DispatcherServlet, Spring MVC szuka pliku nazwa
[Servlet-name] - servlet.xml w katalogu WEB-INF
twojego aplikacji webowej i tworzy zdefiniowane tam fasony, nadpisując definicje dowolnych ziaren zdefiniowanych o tej samej nazwie w globalnej zakres.

Rozważ następującą konfigurację serwletów DispatcherServlet (w www.plik xml):

<web-app>

    <servlet>
        <servlet-name>golfing</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>golfing</servlet-name>
        <url-pattern>/golfing/*</url-pattern>
    </servlet-mapping>

</web-app>


[[163]} o contextConfigLocation i przestrzeni nazw

Z dokumentacji (moja):

Z powyższą konfiguracją serwletów, będziesz musiał mieć plik o nazwie
/WEB-INF/golfing-servlet.xml w aplikacji; to plik będzie zawierał wszystkie komponenty specyficzne dla Spring Web MVC fasola). Możesz zmienić dokładną lokalizację tego pliku konfiguracyjnego poprzez parametr inicjalizacji Serwleta(szczegóły poniżej).
...
Można dostosować poszczególne instancje DispatcherServlet dodając Parametry inicjalizacji serwleta (elementy init-param) do Servlet deklaracja w sieci.plik xml. Lista znajduje się w poniższej tabeli obsługiwanych parametrów.

  • contextClass: Klasa implementująca Webaplicationcontext, która tworzy instancję kontekstu używanego przez ten Servlet. Domyślnie używany jest XmlWebApplicationContext.

  • contextConfigLocation: Łańcuch przekazywany do instancji context (określonej przez contextClass) w celu wskazania, gdzie można znaleźć kontekst. Łańcuch składa się potencjalnie z wielu łańcuchów (używając przecinka jako ogranicznika) do obsługi wielu kontekstów. W przypadku wielu lokalizacji kontekstowych z fasolami zdefiniowanymi dwukrotnie, najnowsza lokalizacja ma pierwszeństwo.

  • przestrzeń nazw: Przestrzeń nazw Webaplicationcontext. Domyślnie [Servlet-name] - servlet.


Teraz zbadajmy dokumentację API dla powiązanych klas. Klasa DispatcherServlet extends abstract class FrameworkServlet. Z FrameworkServlet {[36] } API docs (emfaza):

Przekazuje serwlet INIT-param" contextConfigLocation " do kontekstu instancji, parsowanie go do potencjalnie wielu ścieżek plików, które mogą być oddzielone dowolną liczbą przecinków i spacji, np.
"test-servlet.xml, myServlet.xml". jeśli nie podano wprost, kontekst implementacja ma budować domyślną lokalizację z przestrzeń nazw serwleta .

Domyślną przestrzenią nazw jest "'servlet-name' - servlet", np. " test-servlet" dla servleta-nazwa "test" (prowadząca do "/WEB-INF/test-servlet.xml" domyślna lokalizacja z XmlWebApplicationContext). przestrzeń nazw może również być ustawione jawnie poprzez" przestrzeń nazw " servlet init-param.

To jest fragment FrameworkServlet źródło kod:
/ align = "left" / java

....
/**
* Suffix for WebApplicationContext namespaces. If a servlet of this class is
* given the name "test" in a context, the namespace used by the servlet will
* resolve to "test-servlet".
*/
public static final String DEFAULT_NAMESPACE_SUFFIX = "-servlet";
....


Domyślną klasą kontekstu dla FrameworkServlet jest XmlWebApplicationContext. Z XmlWebApplicationContext {[36] } API docs (emfaza mine):

Domyślnie konfiguracja zostanie pobrana z "/WEB-INF / applicationContext.xml " dla kontekstu głównego oraz "/WEB-INF / test-servlet.xml " dla kontekstu z przestrzenią nazw "test-servlet "(jak na Instancja DispatcherServlet z servlet-nazwa "test").

Domyślne ustawienia lokalizacji konfiguracji można przesłonić za pomocą "contextConfigLocation" context-param ContextLoader i servlet init-param of FrameworkServlet . Lokalizacje Config mogą oznaczać konkretne pliki jak " / WEB-INF / context.xml " lub wzorce w stylu Ant, takie jak "/WEB-INF / *-context.xml " (patrz PathMatcher javadoc dla wzorca szczegóły).

Nadpisywanie domyślnych lokalizacji konfiguracyjnych za pomocą contextConfigLocation jest taki sam jak w powyższym przykładzie dla głównego kontekstu aplikacji.

Jeśli chodzi o nadpisywanie domyślnej przestrzeni nazw {[30] } są pewne ważne momenty. Gdy ustawisz nową przestrzeń nazw, nie dołączaj jej do /WEB-INF i nie dołączaj do niej .xml . Powód tego może być odkryty, jeśli poszukamy w pliku źródłowym klasy xmlwebapplicationcontext :
XmlWebApplicationContext.java

...

/** Default config location for the root context */
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";

/** Default prefix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";

/** Default suffix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";

...

/**
* The default location for the root context is "/WEB-INF/applicationContext.xml",
* and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet"
* (like for a DispatcherServlet instance with the servlet-name "test").
*/
@Override
protected String[] getDefaultConfigLocations() {
    if (getNamespace() != null) {
        return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
    }
    else {
        return new String[] {DEFAULT_CONFIG_LOCATION};
    }
}

Jak widać, kod źródłowy mówi wszystko.


Przykład określenia własnej przestrzeni nazw

www.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">


    <!-- 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>namespace</param-name>
            <param-value>spring/mvc/spring-mvc</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

Rezultatem jest to, że zamiast używać domyślnej przestrzeni nazw do konstruowania ścieżki do pliku konfiguracyjnego, która w przeciwnym razie byłaby /WEB-INF/spring-mvc-servlet.xml, kontener będzie szukał /WEB-INF/spring/mvc/spring-mvc.xml.

Uwaga:
Powyższe wyjaśnienia związane z ustawieniem niestandardowej przestrzeni nazw są dla domyślnej XmlWebApplicationContext Klasa kontekstu. Można określić alternatywną klasę, jak Annotationconfigwebapplicationkontekst, więc będą na to specjalne chwile.


Podsumowanie

Jest (IMHO) znacznie łatwiejsze w użyciu parametr contextConfigLocation do definiowania własnych plików konfiguracyjnych, zarówno dla głównego kontekstu aplikacji, jak i dla poszczególnych kontekstów. Jedyną różnicą jest to, że dla kontekstu aplikacji root używasz <context-param> wewnątrz <web-app> elementu, ale nie wewnątrz określonego servlet (nie zapomnij też o klasie słuchacza). I dla kontekstu dziecięcego, którego używasz <init-param> zagnieżdżone wewnątrz elementu <servlet> dla każdego określonego servletu. Zobacz moje Przykładowe konfiguracje (web.xml ) na samym początku tego postu.

Dodatkowe zasoby (jakby powyższe nie wystarczyło: -)):

 160
Author: informatik01,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 21:50:52

Myślę, że odpowiedź LuckyLuke ma wiele przydatnych informacji, ale nie odpowiada na pytanie. W szczególności, jak działają parametry" namespace "i" contextConfigLocation"?

Jedynym miejscem, gdzie mogłem znaleźć konkretną odpowiedź, jest kod źródłowy:

  • przestrzeń nazw paremeter ustawia niestandardową przestrzeń nazw, która ma być używana do budowania domyślnej context Config location
  • contextconfiglocation parametr ustawia lokalizację konfiguracji kontekstu jawnie, zamiast polegać na domyślnej lokalizacji zbudowanej z przestrzeni nazw
 4
Author: Sava Jcript,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-14 20:05:12

Jaka jest różnica między contextConfigLocation a przestrzenią nazw? contextConfigLocation jest używany do określenia ścieżki plików konfiguracyjnych spring, co oznacza, że zostaną zainicjowane. przestrzeń nazw jest używana do określenia ścieżki i nazwy Dispatcherservleta programu Spring MVC. domyślnie jest to [Dispatcher_name]-servlet.xml, Oto przykład:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>namespace</param-name>
        <param-value>config/spring-mvc</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Spring wyszukuje plik, który będzie używany jako Konfiguracja mvc przy ścieżce /WEB-INF/config/spring-mvc.xml.
czy contextConfigLocation jest przeznaczony tylko do określania folderów gdzie Klasa context może znaleźć definicję XML

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

Powyższy kod pokazał, że podczas uruchamiania aplikacji Spring załaduje wszystkie pliki, których nazwa zaczyna się od' app - 'i kończy się na'.xml " w katalogu WEB-INF / config.

Powinien używać /WEB-INF / application-context.xml? I czy należy określić ścieżki?
Poprzez powyższy przykład możemy wiedzieć, że podczas konfigurowania Springa musimy podać pełną ścieżkę i ogólną nazwę pliku oraz gdy SpringMVC tylko powinniśmy podać ścieżkę (jeśli znajduje się w katalogu, a nie zawierać katalogu WEB-INF) i nazwę(nie zawierać rozszerzenia).
Mam nadzieję, że ci pomogę:)

 3
Author: Hunter Zhao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-04 18:52:57