Różnica między applicationContext.xml i spring-servlet.xml w Spring Framework


373
  • Czy są applicationContext.xmli spring-servlet.xmljakkolwiek powiązane w Spring Framework?
  • Czy zadeklarowane pliki właściwości applicationContext.xmlbędą dostępne dla DispatcherServlet?
  • W powiązanej notatce, dlaczego w ogóle potrzebuję *-servlet.xml? Dlaczego applicationContext.xmlsam jest niewystarczający?

Odpowiedzi:


430

Wiosna pozwala zdefiniować wiele kontekstów w hierarchii rodzic-dziecko.

applicationContext.xmlDefiniuje fasolę do „korzeni kontekście webapp”, czyli kontekstu związanego z webapp.

spring-servlet.xml(Lub czegokolwiek innego, co nazwać) definiuje fasolę dla jednego serwletu app kontekście. Może być ich wiele w aplikacji internetowej, po jednej na serwlet Spring (np. spring1-servlet.xmlDla serwletu spring1, spring2-servlet.xmldla serwletu spring2).

Fasola spring-servlet.xmlmoże odnosić się do fasoli applicationContext.xml, ale nie odwrotnie.

Wszystkie kontrolery Spring MVC muszą działać w spring-servlet.xmlkontekście.

W najprostszych przypadkach applicationContext.xmlkontekst jest niepotrzebny. Zasadniczo jest używany do przechowywania komponentów bean, które są wspólne dla wszystkich serwletów w aplikacji internetowej. Jeśli masz tylko jeden serwlet, to nie ma większego sensu, chyba że masz do niego określone zastosowanie.


30
dlaczego miałbyś mieć wiele serwletów wiosennych?
NimChimpsky

5
potężna silna odpowiedź (z powodu zwięzłości)
amfibia

35
@NimChimpsky czasem przydatne jest oddzielenie części aplikacji, które w innym przypadku mogłyby spowodować konflikt w tym samym kontekście. Jako przykład możesz mieć usługi ReST i standardowe widoki, możesz mieć różne programy tłumaczące lub obawy dotyczące bezpieczeństwa usług w odniesieniu do widoków.
Brett Ryan,

12
Ludzie powinni zobaczyć tę odpowiedź przed przeczytaniem dokumentacji i opracowaniem aplikacji! W normalnych przypadkach nie ma potrzeby posiadania ContextLoaderListener i contextConfigLocation, tylko DispatcherServlet!
ruruskyi

24
W wielu samouczkach kontekstConfigLocation zawiera plik dispatcher-servlet.xml oraz DispatcherServlet. To powoduje, że fasola jest inicjowana dwukrotnie!
ruruskyi

106

Scenariusz 1

W aplikacji klienckiej (aplikacja nie jest aplikacją internetową, np. Może być aplikacją swing)

private static ApplicationContext context = new  ClassPathXmlApplicationContext("test-client.xml");

context.getBean(name);

Nie ma potrzeby pliku web.xml . ApplicationContext jako kontener umożliwiający uzyskanie usługi bean. Nie ma potrzeby kontenera serwera WWW. W test-client.xml może być Prosta fasola bez zdalnego, fasola z pilotem.

Wniosek : w scenariuszu 1 aplikacjaContext i DispatcherServletnie są powiązane.

Scenariusz 2

W aplikacji serwerowej (aplikacja wdrożona na serwerze np. Tomcat). Dostęp do usługi poprzez zdalne sterowanie z programu klienckiego (np. Aplikacja Swing)

Zdefiniuj detektor w pliku web.xml

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

Podczas uruchamiania serwera tworzy ContextLoaderListenerinstancję komponentów bean zdefiniowanych w applicationContext.xml .

Zakładając, że w pliku applicationContext.xml zdefiniowano następujące elementy :

<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />

Ziarna tworzone są ze wszystkich czterech plików konfiguracyjnych test1.xml , test2.xml , test3.xml , test4.xml .

Wniosek : w scenariuszu 2 ApplicationContext i DispatcherServletnie są powiązane.

Scenariusz 3

W aplikacji internetowej ze sprężyną MVC.

W pliku web.xml zdefiniuj:

<servlet>
    <servlet-name>springweb</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    
</servlet>

<servlet-mapping>
    <servlet-name>springweb</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

Po uruchomieniu Tomcat tworzone są instancje ziaren zdefiniowanych w pliku springweb-servlet.xml . DispatcherServletrozszerza się FrameworkServlet. W FrameworkServletinstancji fasoli zachodzi tworzenie Springweb. W naszym przypadku springweb to FrameworkServlet.

Wniosek : w scenariuszu 3 aplikacjiContext i DispatcherServletnie są powiązane.

Scenariusz 4

W aplikacji internetowej ze sprężyną MVC. springweb-servlet.xml dla serwletu i applicationContext.xml do uzyskiwania dostępu do usługi biznesowej w programie serwera lub do uzyskiwania dostępu do usługi DB w innym programie serwera.

W pliku web.xml zdefiniowano:

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

<servlet>
    <servlet-name>springweb</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        
</servlet>

<servlet-mapping>
    <servlet-name>springweb</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

Podczas uruchamiania serwera tworzy ContextLoaderListenerinstancję komponentów bean zdefiniowanych w applicationContext.xml ; zakładając, że zadeklarowałeś tutaj:

<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />

Wszystkie instancje są tworzone z wszystkich czterech test1.xml , test2.xml , test3.xml , test4.xml . Po zakończeniu fasoli instancji określonej w applicationContext.xml , ziarna określono w springweb-servlet.xml są wystąpienia.

Kolejność tworzenia instancji to: root (kontekst aplikacji), a następnie FrameworkServlet.

Teraz powinno być jasne, dlaczego są one ważne w jakim scenariuszu.


10
+1. Bardzo dobrze. Szukałem tego rodzaju porównania, ale nigdy nie znalazłem.
Ninad Pingale,

@abishkar bhattarai bardzo dobrze, moje pytanie brzmi: więc co się stanie, jeśli użyję adnotacji @ Component i @ Value do stworzenia fasoli, gdy „Scenariusz 4”
Lawrence

springweb DispatcherServletnie zadzwoni, jeśli adres URL nie kończy się na .action?
Asif Mushtaq

@lawrence Nadal będziesz musiał określić ścieżkę klasy w pliku springweb-servlet.xml, aby Spring mógł znaleźć ten składnik podczas skanowania.
veritas

54

Jeszcze jeden punkt, który chcę dodać. W spring-servlet.xmlzaliczamy skanowanie składnik pakietu sterownika. W poniższym przykładzie dołączamy adnotację filtru dla pakietu kontrolera.

<!-- Scans for annotated @Controllers in the classpath -->
<context:component-scan base-package="org.test.web" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

W applicationcontext.xmldodajemy filtr dla pozostałego pakietu oprócz kontrolera.

<context:component-scan base-package="org.test">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

9
dlaczego ? Dlaczego nie przeskanować całości raz?
NimChimpsky

3
@NimChimpsky Musisz przeskanować @Controllerziarna w kontekście serwletu (wymagane przez Spring MVC).
Tuukka Mustonen

3
Dlaczego nie wszystko może dwa razy? Dlaczego warto włączyć / wyłączyć?
Mike Rylander

8
Należy również dodać atrybut use-default-
filter

4
Rakesh Waghela ma rację. Bez tego atrybutu Fasole kontrolera zostaną utworzone dwukrotnie. Po pierwsze w appContext, a po drugie w servletContext
UltraMaster

12

W prostych słowach

applicationContext.xmldefiniuje komponenty bean, które są współużytkowane przez wszystkie serwlety. Jeśli twoja aplikacja ma więcej niż jeden serwlet, applicationContext.xmlbardziej sensowne byłoby zdefiniowanie wspólnych zasobów .

spring-servlet.xmldefiniuje komponenty bean, które są powiązane tylko z tym serwletem. Oto serwlet dyspozytora. Zatem kontrolery Spring MVC muszą być zdefiniowane w tym pliku.

Nie ma nic złego w definiowaniu wszystkich komponentów bean, spring-servlet.xmljeśli używasz tylko jednego serwletu w aplikacji internetowej.


3
Mogę zdefiniować wszystkie ziarna w pliku spring-servlet.xml, ale w tym przypadku powinna istnieć również applicationContext.xml, która może być pusta (bez ziaren). Poprawny?
Michaił Kopylow,

6

W technologii serwletów, jeśli chcesz przekazać dane wejściowe do konkretnego serwletu, musisz przekazać parametr init jak poniżej.

 <servlet>
    <servlet-name>DBController</servlet-name>
    <servlet-class>com.test.controller.DBController</servlet-class>
    <init-param>
        <param-name>username</param-name>
        <param-value>John</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>DBController</servlet-name>
    <url-pattern>/DBController</url-pattern>
</servlet-mapping>

Jeśli chcesz przekazać część, która jest wspólna dla wszystkich serwletów, musisz skonfigurować parametry kontekstu. Przykład

 <context-param>
    <param-name>email</param-name>
    <param-value>admin@example.com</param-value>
</context-param>

Tak więc dokładnie tak, jak kiedykolwiek, kiedy pracujemy z Spring MVC, musimy podać pewne informacje do predefiniowanego serwletu dostarczonego przez Spring, czyli DispatcherServlet poprzez parametr początkowy. Tak więc konfiguracja jest następująca, tutaj dostarczamy plik spring-servlet.xml jako parametr init dla DispatcherServlet.

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
              http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>Spring MVC App</display-name>

    <servlet>
        <servlet-name>SpringController</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>SpringController</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
</web-app>

Ponownie potrzebujemy param kontekstu. Dotyczy to całej aplikacji. Możemy więc podać kontekst główny, czyli applicationcontext.xml Konfiguracja wygląda następująco:

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationcontext.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
        <servlet-name>SpringController</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>SpringController</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

4

Konteksty aplikacji zapewniają sposób rozwiązywania wiadomości tekstowych, w tym obsługę i18n tych wiadomości. Konteksty aplikacji zapewniają ogólny sposób ładowania zasobów plików, takich jak obrazy. Konteksty aplikacji mogą publikować zdarzenia w komponentach bean, które są zarejestrowane jako detektory. Niektóre operacje na kontenerze lub fasoli w kontenerze, które muszą być obsługiwane w sposób zautomatyzowany za pomocą fabryki fasoli, mogą być obsługiwane deklaratywnie w kontekście aplikacji. Obsługa ResourceLoader: Interfejs Resource Springa elastyczna abstrakcja ogólna do obsługi zasobów niskiego poziomu. Sam kontekst aplikacji to ResourceLoader, dlatego zapewnia aplikacji dostęp do instancji zasobów specyficznych dla wdrożenia. Obsługa MessageSource: kontekst aplikacji implementuje MessageSource, interfejs używany do uzyskiwania zlokalizowanych komunikatów,

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.