2010-09-06 17 views
317
  • son applicationContext.xml y spring-servlet.xml relacionados de cualquier modo en el Marco de la primavera?
  • ¿Los archivos de propiedades declarados en applicationContext.xml estarán disponibles para DispatcherServlet?
  • En una nota relacionada, ¿por qué necesito un *-servlet.xml en absoluto? ¿Por qué el applicationContext.xml es solo insuficiente?
+1

Ver esto también. http://stackoverflow.com/questions/11708967/what-is-the-difference-between-applicationcontext-and-webapplicationcontext-in-s –

Respuesta

379

Spring le permite definir contextos múltiples en una jerarquía de elementos primarios y secundarios.

El applicationContext.xml define los beans para el "contexto raíz de la aplicación web", es decir, el contexto asociado con la aplicación web.

El spring-servlet.xml (o como se llame) define los beans para el contexto de una aplicación de servlet. Puede haber muchos de estos en una aplicación web, uno por servlet de Spring (por ejemplo, spring1-servlet.xml para el servlet spring1, spring2-servlet.xml para el servlet spring2).

Los frijoles en spring-servlet.xml pueden hacer referencia a los frijoles en applicationContext.xml, pero no al revés.

Todos los controladores Spring MVC deben ir en el contexto spring-servlet.xml.

En la mayoría de los casos simples, el contexto applicationContext.xml es innecesario. Generalmente se usa para contener beans que se comparten entre todos los servlets en una aplicación web. Si solo tiene un servlet, entonces no tiene mucho sentido, a menos que tenga un uso específico para él.

+25

¿por qué tendría múltiples servlets de resorte? – NimChimpsky

+0

Acerca de su comentario _Todos los controladores Spring MVC deben ir en spring-servlet.xml context._, ¿dónde puedo encontrarlos en la referencia oficial de Spring? –

+0

@CKLee, cuando los muevo al contexto de la aplicación raíz, Spring MVC no procesa ningún '@ RequestMapping'. Al menos, eso es lo que recordé, y una prueba rápida lo confirmó. Sin embargo, [algunos no tienen problemas] (http://stackoverflow.com/questions/10019426/spring-transactional-not-working/10021874#comment12812351_10019426) moviendo el escaneo de '@ Controller' al contexto raíz, parece, por lo que Podría estar equivocado. – Arjan

51

Un punto más que quiero agregar. En spring-servlet.xml incluimos el escaneo de componentes para el paquete del Controlador. En el siguiente ejemplo, incluimos la anotación de filtro para el paquete del controlador.

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

En applicationcontext.xml que agregar el filtro de paquete restante sin unidad de control.

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

¿por qué? ¿Por qué no solo escanea todo una vez? – NimChimpsky

+3

@NimChimpsky Debe escanear beans '@ Controller' en contexto de servlet (requerido por Spring MVC). –

+3

¿Por qué no puede todo esto dos veces? ¿Por qué incluir/excluir? –

90

Escenario 1

En aplicación cliente (la aplicación no es de aplicación web, por ejemplo puede ser la aplicación oscilación)

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

context.getBean(name); 

No hay necesidad de web.xml. ApplicationContext como contenedor para obtener servicio de frijoles. No hay necesidad de contenedor de servidor web. En test-client.xml puede haber beans simples sin comunicación remota, beans con comunicación remota.

Conclusión: En el escenario 1 applicationContext y DispatcherServlet no están relacionados.

Escenario 2

En una aplicación de servidor (aplicación implementada en el servidor por ejemplo Tomcat). Servicio accedido mediante comunicación remota desde el programa del cliente (p.g aplicación Swing)

Definir oyente en web.xml

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

al iniciar el servidor ContextLoaderListener instancia granos definidos en applicationContext.xml.

Suponiendo que usted ha definido el siguiente en applicationContext.xml:

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

Los granos se crean instancias de los cuatro archivos de configuración test1.xml, test2.xml, test3.xml , test4.xml.

Conclusión: En el escenario 2 applicationContext y DispatcherServlet no están relacionados.

Escenario 3

En una aplicación de web con el resorte MVC.

En Web.xml definen:

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

Cuando se inicia Tomcat, beans definidos en el Spring -servlet.xml se crean instancias. DispatcherServlet extiende FrameworkServlet. En FrameworkServlet se realiza una instanciación de frijol para springweb. En nuestro caso springweb es FrameworkServlet.

Conclusión: En el escenario 3 applicationContext y DispatcherServlet no están relacionados.

Escenario 4

En aplicación web con Spring MVC. springweb-servlet.xml para servlet y applicationContext.xml para acceder al servicio comercial dentro del programa servidor o para acceder al servicio DB en otro programa servidor.

En Web.xml se definen los siguientes:

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

En el inicio del servidor, crea una instancia ContextLoaderListener beans definidos en applicationContext.xml; suponiendo que ha declarado en el presente documento:

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

Los granos están instanciados a partir de los cuatro test1.xml, test2.xml, test3.xml, test4.xml. Después de completar la instanciación de beans definida en applicationContext.xml luego los beans definidos en springweb-servlet.xml se crean instancias.

Por lo tanto, la orden de instanciación es la raíz es el contexto de la aplicación, luego FrameworkServlet.

Ahora deja en claro por qué son importantes en qué escenario.

+8

+1. Muy bien. Estaba buscando este tipo de comparación, pero nunca la encontré. –

+0

buena comparación +1 –

+0

@abishkar bhattarai muy bien, mi pregunta es: entonces, ¿qué ocurre si se usa @ Component y @ Value para crear bean cuando "Escenario 4" – lawrence

3

Los contextos de aplicación proporcionan un medio para resolver mensajes de texto, incluido el soporte para i18n de esos mensajes. Los contextos de aplicación proporcionan una forma genérica de cargar recursos de archivos, como imágenes. Los contextos de aplicación pueden publicar eventos en beans que están registrados como escuchas. Algunas operaciones en el contenedor o los frijoles en el contenedor, que deben manejarse de forma programática con una fábrica de beans, pueden manejarse de manera declarativa en un contexto de aplicación. Soporte de ResourceLoader: Spring's Resource es una abstracción genérica flexible para el manejo de recursos de bajo nivel. Un contexto de aplicación en sí mismo es un ResourceLoader, por lo tanto, proporciona una aplicación con acceso a instancias de recursos específicos de la implementación. apoyo MessageSource: El contexto de aplicación implementa MessageSource, una interfaz que se utiliza para obtener mensajes localizados, siendo la aplicación efectiva enchufable

9

En palabras sencillas,

applicationContext.xml define los granos que son compartidos entre todos los servlets. Si su aplicación tiene más de un servlet, entonces la definición de los recursos comunes en el applicationContext.xml tendría más sentido.

spring-servlet.xml define los beans que están relacionados solo con ese servlet. Aquí está el servlet despachador. Entonces, sus controladores Spring MVC deben estar definidos en este archivo.

No hay nada de malo en definir todos los beans en el spring-servlet.xml si está ejecutando solo un servlet en su aplicación web.

+2

puedo definir todos los beans en spring-servlet.xml, pero también debe haber applicationContext.xml que puede estar vacío (sin beans) en este caso. ¿Correcto? – omickron

0

En la tecnología Servlet, si desea pasar cualquier entrada a un servlet en particular, entonces debe pasar el parámetro init para el siguiente código.

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

Si desea pasar algunos en venta que es común para todos los servlets luego que el tiempo que necesita para configurar parámetro de contexto. Ejemplo

<context-param> 
    <param-name>email</param-name> 
    <param-value>[email protected]</param-value> 
</context-param> 

tan exactamente como esta, cuando cada vez que estamos trabajando con Spring MVC que deberá proporcionar alguna información al servlet predefinidas de primavera que es DispatcherServlet través parámetro init. Entonces la configuración es como barbechos, aquí proporcionamos spring-servlet.xml como parámetro init para 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> 

De nuevo, necesitamos algunos parámetros de contexto. Eso es aplicable para toda la aplicación. para que podamos ofrecer el contexto raíz que es applicationContext.xml La configuración es la siguiente:

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