Was ist der Unterschied zwischen ApplicationContext und WebApplicationContext in Spring MVC?

193

Was ist der Unterschied zwischen Anwendungskontext und Webanwendungskontext?

Mir ist bekannt, dass WebApplicationContextfür Spring MVC Architektur-orientierte Anwendungen verwendet wird?

Ich möchte wissen, was ApplicationContextin MVC-Anwendungen verwendet wird. Und in welcher Art von Bohnen ist definiert ApplicationContext?

Sumit Trehan
quelle
5
Ich glaube nicht, dass dies ein Duplikat von stackoverflow.com/questions/3652090/ ist. Diese Frage fragt nach dem Inhalt der web.xmlDatei. Diese Frage bezieht sich auf einige Frühlingsklassen.
Raedwald
@ Raedwald das stimmt nicht. Bei der anderen Frage geht es nicht web.xmlum die Spring XML Bean-Konfigurationsvarianten von ApplicationContextund WebApplicationContext. Alle Bean-Definitionen in applicationContext.xmlsind in verfügbar, ApplicationContextwährend alle Bean-Definitionen in *-servlet.xmlin verfügbar sind WebApplicationContext.
g00glen00b

Antworten:

228

Webanwendungskontext erweitert Anwendungskontext, der für die Verwendung mit dem Standard javax.servlet.ServletContext ausgelegt ist, damit er mit dem Container kommunizieren kann.

public interface WebApplicationContext extends ApplicationContext {
    ServletContext getServletContext();
}

In WebApplicationContext instanziierte Beans können auch ServletContext verwenden, wenn sie die ServletContextAware-Schnittstelle implementieren

package org.springframework.web.context;
public interface ServletContextAware extends Aware { 
     void setServletContext(ServletContext servletContext);
}

Mit der ServletContext-Instanz können viele Dinge getan werden, z. B. der Zugriff auf WEB-INF-Ressourcen (XML-Konfigurationen usw.) durch Aufrufen der Methode getResourceAsStream (). In der Regel sind alle in web.xml in einer Servlet Spring-Anwendung definierten Anwendungskontexte Webanwendungskontexte. Dies gilt sowohl für den Stamm-Webapp-Kontext als auch für den App-Kontext des Servlets.

Abhängig vom Kontext der Webanwendung kann es außerdem schwieriger sein, Ihre Anwendung zu testen, und Sie müssen möglicherweise die MockServletContext- Klasse zum Testen verwenden.

Unterschied zwischen Servlet- und Root-Kontext Mit Spring können Sie mehrstufige Anwendungskontexthierarchien erstellen, sodass die erforderliche Bean aus dem übergeordneten Kontext abgerufen wird, wenn sie im aktuellen Anwendungskontext nicht vorhanden ist. In Webanwendungen gibt es standardmäßig zwei Hierarchieebenen: Root- und Servlet-Kontexte : Servlet- und Root-Kontext.

Auf diese Weise können Sie einige Dienste als Singletons für die gesamte Anwendung ausführen (Spring Security-Beans und grundlegende Datenbankzugriffsdienste befinden sich normalerweise hier) und andere als separate Dienste in den entsprechenden Servlets, um Namenskonflikte zwischen Beans zu vermeiden. Beispielsweise wird ein Servlet-Kontext die Webseiten bedienen und ein anderer wird einen zustandslosen Webdienst implementieren.

Diese Trennung auf zwei Ebenen ist sofort einsatzbereit, wenn Sie die Spring-Servlet-Klassen verwenden: Um den Kontext der Stammanwendung zu konfigurieren, sollten Sie in Ihrer web.xml das Tag context-param verwenden

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/root-context.xml
            /WEB-INF/applicationContext-security.xml
    </param-value>
</context-param>

(Der Stammanwendungskontext wird von ContextLoaderListener erstellt, der in web.xml deklariert ist

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

) und Servlet- Tag für die Servlet-Anwendungskontexte

<servlet>
   <servlet-name>myservlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>app-servlet.xml</param-value>
   </init-param>
</servlet>

Bitte beachten Sie, dass spring in diesem Beispiel myservlet-servlet.xml verwendet, wenn init-param weggelassen wird.

Siehe auch: Unterschied zwischen applicationContext.xml und spring-servlet.xml in Spring Framework

Boris Treukhov
quelle
2
Vielen Dank für die Antwort. Ich habe gehört, dass es zwei Arten von Kontexten gibt, die auch für eine Webanwendung verwendet werden. Einer dient als Stammanwendungskontext, in dem nicht webbezogene Definitionen als Beispieldienst, Dao-Konfigurationen usw. bereitgestellt werden, und der andere dient als webspezifische Konfiguration wie Handlerzuordnungen usw. Der vorherige dient als übergeordneter Kontext und der letztere als untergeordneter Kontext . Ich möchte wissen, wie man diese Struktur deklariert. Ich habe von einigen ContextListener-Rückrufen gehört. Aber ich bin ziemlich unklar.
Sumit Trehan
1
Eine solche Struktur ist in Spring-Servlet-Tools fest codiert. Es gibt immer mindestens zwei Anwendungskontexte in der Spring-Web-App. Siehe die aktualisierte Antwort. Ich hoffe, es hilft.
Boris Treukhov
Ausgezeichnete Beschreibung. Ich hatte einige Zweifel an diesem Szenario. Als ich mich in der Anfangsphase befand, fand ich Ihre nützliche Antwort, um etwas Wissen zu
erlangen
"Die erforderliche Bean wird aus dem übergeordneten Kontext abgerufen, wenn sie im aktuellen Anwendungskontext nicht vorhanden ist." Können Sie erklären, wie? Wie kann ein Webanwendungskontext auf Beans im Stammanwendungskontext zugreifen? Link zu einem Beispiel?
Anir
14

Zurück zu den Servlet-Tagen kann web.xml nur eines haben <context-param>, sodass nur ein Kontextobjekt erstellt wird, wenn der Server eine Anwendung lädt und die Daten in diesem Kontext von allen Ressourcen gemeinsam genutzt werden (Beispiel: Servlets und JSPs). Dies entspricht dem Namen des Datenbanktreibers im Kontext, der sich nicht ändert. In ähnlicher Weise wird beim Deklarieren des Parameters contextConfigLocation in <contex-param>Spring ein Anwendungskontextobjekt erstellt.

 <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.myApp.ApplicationContext</param-value>
 </context-param>

Sie können mehrere Servlets in einer Anwendung haben. Beispielsweise möchten Sie möglicherweise / Secure / * -Anfragen auf eine Weise und / non-seucre / * auf eine andere Weise behandeln. Für jedes dieser Servlets können Sie ein Kontextobjekt haben, bei dem es sich um einen WebApplicationContext handelt.

<servlet>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.secure.SecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <url-pattern>/secure/*</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.non-secure.NonSecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <url-pattern>/non-secure/*</url-patten>
</servlet-mapping>
Ben Tennyson
quelle
13

Die akzeptierte Antwort ist durch, aber es gibt eine offizielle Erklärung dazu:

Der WebApplicationContext ist eine Erweiterung des einfachen ApplicationContext, die einige zusätzliche Funktionen enthält, die für Webanwendungen erforderlich sind. Es unterscheidet sich von einem normalen ApplicationContext dadurch, dass es Themen auflösen kann (siehe Verwenden von Themen) und weiß, mit welchem ​​Servlet es verknüpft ist (indem es einen Link zum ServletContext hat). Der WebApplicationContext ist im ServletContext gebunden. Mithilfe statischer Methoden für die RequestContextUtils-Klasse können Sie den WebApplicationContext jederzeit nachschlagen, wenn Sie Zugriff darauf benötigen.

Zitiert aus der Spring Web Framework Referenz

Übrigens sind Servlet und Root-Kontext beide webApplicationContext:

Typische Kontexthierarchie in Spring Web MVC

Nick Allen
quelle
6

ApplicationContext (Stammanwendungskontext): Jede Spring MVC-Webanwendung verfügt über eine applicationContext.xml-Datei, die als Stamm der Kontextkonfiguration konfiguriert ist. Spring lädt diese Datei und erstellt einen applicationContext für die gesamte Anwendung. Diese Datei wird vom ContextLoaderListener geladen, der als Kontextparameter in der Datei web.xml konfiguriert ist. Und es wird nur einen applicationContext pro Webanwendung geben.

WebApplicationContext: WebApplicationContext ist ein webfähiger Anwendungskontext, dh er enthält Servlet-Kontextinformationen. Eine einzelne Webanwendung kann mehrere WebApplicationContext enthalten, und jedes Dispatcher-Servlet (das der Front-Controller der Spring MVC-Architektur ist) ist einem WebApplicationContext zugeordnet. Die Konfigurationsdatei web-ApplicationContext * -servlet.xml ist spezifisch für ein DispatcherServlet. Da für eine Webanwendung mehr als ein Dispatcher-Servlet konfiguriert sein kann, um mehrere Anforderungen zu bedienen, kann es pro Webanwendung mehr als eine webApplicationContext-Datei geben.

Hetal Rachh
quelle
3

Der von der WebApplicationContextSchnittstelle angegebene Webanwendungskontext ist ein Spring-Anwendungskontext für Webanwendungen. Es verfügt über alle Eigenschaften eines regulären Spring-Anwendungskontexts, vorausgesetzt, die WebApplicationContextSchnittstelle erweitert die ApplicationContextSchnittstelle und fügt eine Methode zum Abrufen der Standard-Servlet-API ServletContextfür die Webanwendung hinzu.

Zusätzlich zu den Standardbereichen von Spring Bean singletonund prototypestehen in einem Webanwendungskontext drei zusätzliche Bereiche zur Verfügung:

  • request- legt eine einzelne Bean-Definition auf den Lebenszyklus einer einzelnen HTTP-Anforderung fest; Das heißt, jede HTTP-Anforderung verfügt über eine eigene Instanz einer Bean, die auf der Rückseite einer einzelnen Bean-Definition erstellt wurde
  • session - legt eine einzelne Bean-Definition auf den Lebenszyklus einer HTTP-Sitzung fest
  • application - legt eine einzelne Bean-Definition auf den Lebenszyklus von a ServletContext
DimaSan
quelle