Differenza tra applicationContext.xml e spring-servlet.xml in Spring Framework


373
  • Sono applicationContext.xmle spring-servlet.xmlcorrelati comunque in Spring Framework?
  • I file delle proprietà dichiarati in applicationContext.xmlsaranno disponibili per DispatcherServlet?
  • In una nota correlata, perché ho bisogno di un *-servlet.xmlaffatto? Perché applicationContext.xmlda solo è insufficiente?

Risposte:


430

Spring ti consente di definire più contesti in una gerarchia padre-figlio.

La applicationContext.xmldefinisce i fagioli per il "contesto webapp root", cioè la rapida associato webapp.

Il spring-servlet.xml(o come lo chiami) definisce i bean per il contesto dell'app di un servlet. Ci possono essere molti di questi in una webapp, uno per servlet Spring (ad esempio spring1-servlet.xmlper servlet spring1, spring2-servlet.xmlper servlet spring2).

I fagioli in spring-servlet.xmlpossono fare riferimento a fagioli in applicationContext.xml, ma non viceversa.

Tutti i controller Spring MVC devono entrare nel spring-servlet.xmlcontesto.

Nella maggior parte dei casi semplici, il applicationContext.xmlcontesto non è necessario. Viene generalmente utilizzato per contenere bean condivisi tra tutti i servlet in una webapp. Se hai un solo servlet, allora non ha molto senso, a meno che tu non ne abbia un uso specifico.


30
perché dovresti avere più servlet a molla?
NimChimpsky,

5
potente potente risposta (a causa della sintonia)
anfibio

35
@NimChimpsky è talvolta utile separare parti dell'applicazione che potrebbero altrimenti essere in conflitto nello stesso contesto. Ad esempio, potresti avere servizi ReST e viste standard, quindi potresti avere diversi risolutori di vista o problemi di sicurezza per i servizi rispetto alle viste.
Brett Ryan,

12
Le persone dovrebbero vedere questa risposta prima di leggere la documentazione e sviluppare app! In casi normali non è necessario avere ContextLoaderListener e contextConfigLocation, solo DispatcherServlet!
Ruruskyi,

24
In molte esercitazioni contextConfigLocation contiene dispatcher-servlet.xml e DispatcherServlet. Questo fa sì che i bean vengano inizializzati due volte!
Ruruskyi,

106

scenario 1

Nell'applicazione client (l'applicazione non è un'applicazione Web, ad esempio può essere un'app swing)

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

context.getBean(name);

Non c'è bisogno di web.xml . ApplicationContext come contenitore per ottenere il servizio bean. Non è necessario il contenitore del server Web. In test-client.xml possono esserci bean semplici senza remoting, bean con remoting.

Conclusione : in Scenario 1 applicationContext e DispatcherServletnon sono correlati.

Scenario 2

In un'applicazione server (applicazione distribuita nel server, ad esempio Tomcat). Servizio accessibile tramite telecomando dal programma client (ad es. App Swing)

Definisci listener in web.xml

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

All'avvio del server ContextLoaderListenercrea istanze dei bean definiti in applicationContext.xml .

Supponendo di aver definito quanto segue in applicationContext.xml :

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

I bean sono istanziati da tutti e quattro i file di configurazione test1.xml , test2.xml , test3.xml , test4.xml .

Conclusione : in Scenario 2 applicationContext e DispatcherServletnon sono correlati.

Scenario 3

In un'applicazione Web con MVC di primavera.

In web.xml definire:

<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>

All'avvio di Tomcat, i bean definiti in springweb-servlet.xml vengono istanziati. DispatcherServletsi estende FrameworkServlet. In FrameworkServletfagiolo istanziazione avviene per springweb. Nel nostro caso springweb è FrameworkServlet.

Conclusione : in Scenario 3 applicationContext e DispatcherServletnon sono correlati.

Scenario 4

In applicazione web con MVC di primavera. springweb-servlet.xml per servlet e applicationContext.xml per accedere al servizio business nel programma server o per accedere al servizio DB in un altro programma server.

In web.xml sono definiti:

<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>

All'avvio del server, ContextLoaderListeneristanzia i bean definiti in applicationContext.xml ; supponendo che tu abbia dichiarato qui:

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

I bean sono tutti istanziati da tutti e quattro i test1.xml , test2.xml , test3.xml , test4.xml . Dopo il completamento dell'istanza del bean definita in applicationContext.xml , vengono istanziati i bean definiti in springweb-servlet.xml .

Quindi l'ordine di istanza è: root (contesto dell'applicazione), quindi FrameworkServlet.

Ora dovrebbe essere chiaro il motivo per cui sono importanti in quale scenario.


10
+1. Molto bene Stavo cercando questo tipo di confronto, ma non l'ho mai trovato.
Ninad Pingale,

@abishkar bhattarai molto bene, la mia domanda è: quindi cosa succede se si usa l'annotazione @ Component e @ Value per creare un bean quando "Scenario 4"
lawrence

springweb DispatcherServletnon verrà chiamato se l'URL non termina con .action?
Asif Mushtaq,

@lawrence Dovrai comunque specificare il percorso della classe in springweb-servlet.xml in modo che Spring possa trovare quel componente nella sua scansione.
veritas

54

Un altro punto che voglio aggiungere. In spring-servlet.xmlincludiamo scansione componente per il pacchetto di controllo. Nel seguente esempio includiamo l'annotazione del filtro per il pacchetto controller.

<!-- 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>

In applicationcontext.xmlaggiungiamo il filtro per il pacchetto rimanente escluso il controller.

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

9
perché ? Perché non scansionare l'intera cosa una volta?
NimChimpsky,

3
@NimChimpsky Devi scansionare i @Controllerbean nel contesto servlet (richiesto da Spring MVC).
Tuukka Mustonen,

3
Perché non è tutto possibile due volte? Perché includere / escludere?
Mike Rylander,

8
Si dovrebbe anche aggiungere l'attributo use-default-filters = "false" in spring-servlet.xml
Rakesh Waghela,

4
Rakesh Waghela ha ragione. Senza tale attributo, i bean controller verranno creati due volte. In primo luogo in appContext e in secondo luogo in servletContext
UltraMaster il

12

In parole semplici,

applicationContext.xmldefinisce i bean che sono condivisi tra tutti i servlet. Se la tua applicazione ha più di un servlet, la definizione delle risorse comuni in applicationContext.xmlavrebbe più senso.

spring-servlet.xmldefinisce i bean correlati solo a quel servlet. Ecco il servlet del dispatcher. Pertanto, i controller Spring MVC devono essere definiti in questo file.

Non c'è nulla di sbagliato nel definire tutti i bean nel spring-servlet.xmlse si esegue solo un servlet nella propria applicazione web.


3
Posso definire tutti i bean in spring-servlet.xml, ma in questo caso dovrebbe esserci anche applicationContext.xml che potrebbe essere vuoto (senza bean). Corretta?
Mikhail Kopylov,

6

Nella tecnologia Servlet se si desidera passare qualsiasi input a un particolare servlet, è necessario passare a init param come sotto il codice.

 <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>

Se si desidera passare alcuni in put che è comune per tutti i servlet, allora è necessario configurare il parametro di contesto. Esempio

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

Così esattamente quando lavoriamo con Spring MVC, dobbiamo fornire alcune informazioni al servlet predefinito fornito da Spring, ovvero DispatcherServlet tramite init param. Quindi la configurazione è come maggese, qui stiamo fornendo spring-servlet.xml come parametro init a 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>

Ancora una volta abbiamo bisogno di alcuni parametri di contesto. Questo è applicabile per l'intera applicazione. Quindi possiamo fornire il contesto root che è applicationcontext.xml La configurazione è così:

    <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

I contesti applicativi forniscono un mezzo per risolvere i messaggi di testo, incluso il supporto per i18n di tali messaggi. I contesti applicativi forniscono un modo generico per caricare risorse di file, come le immagini. I contesti applicativi possono pubblicare eventi su bean registrati come listener. Alcune operazioni sul contenitore o sui bean nel contenitore, che devono essere gestite in modo programmatico con una fabbrica di bean, possono essere gestite in modo dichiarativo in un contesto applicativo. Supporto per ResourceLoader: Spring's Resource ci interfaccia con un'astrazione generica flessibile per la gestione di risorse di basso livello. Un contesto applicativo stesso è un ResourceLoader, quindi fornisce un'applicazione con accesso a istanze di risorse specifiche della distribuzione. Supporto MessageSource: il contesto dell'applicazione implementa MessageSource, un'interfaccia utilizzata per ottenere messaggi localizzati,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.