java - español - Spring MVC: diferencia entre las etiquetas<context: component-scan> y<annotation-driven/>?
spring mvc español (3)
Annotation-driven indica a Spring que debería escanear en busca de beans anotados, y no solo confiar en la configuración de beans XML. El escaneo de componentes indica dónde buscar esos frijoles.
Aquí hay algunos documentos: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config-enable
Esta pregunta ya tiene una respuesta aquí:
Hace algunos días comencé a estudiar este tutorial de Spring Hello World: http://viralpatel.net/blogs/spring-3-mvc-create-hello-world-application-spring-3-mvc/
En este tutorial Spring DispatcherServlet se configura utilizando el archivo spring-servlet.xml , este:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="net.viralpatel.spring3.controller" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
En este archivo estoy usando el contexto: etiqueta component-scan para decir que Spring tiene que escanear mi archivo buscando la anotación, así por ejemplo, cuando la clase del controlador descubre que un método está anotado por @RequestMapping ("/ hello") anotación sabe que este método maneja la solicitud HTTP hacia la URL que termina con "/ hello". Esto es simple...
Ahora mi duda está relacionada con el proyecto de plantilla de Spring MVC que pude construir automáticamente en STS / Eclipse.
Cuando creo un nuevo proyecto Spring MVC en STS tengo que mi DispatcherServlet está configurado por un archivo llamado servlet-context.xml que contiene alguna configuración similar al archivo de ejemplo anterior.
En este archivo, todavía tengo la etiqueta de exploración de componentes:
<context:component-scan base-package="com.mycompany.maventestwebapp" />
pero también tengo otra etiqueta (que parece tener una tarea similar), esta:
<annotation-driven />
¿Cuál es la diferencia entre estas dos etiquetas?
Otra cosa "extraña" es que el ejemplo anterior (que no usa la etiqueta impulsada por la anotación) es muy similar al proyecto creado por STS usando el proyecto Spring MVC Template, pero si elimino la etiqueta impulsada por la anotación de su configuración archivar el proyecto no se ejecute y déme el siguiente error: HTTP Status 404 -
Y en la stacktrace tengo:
WARN: org.springframework.web.servlet.PageNotFound - No se encontró una asignación para la solicitud HTTP con URI [/ maventestwebapp /] en DispatcherServlet con el nombre ''appServlet''
¿Pero por qué? El ejemplo anterior funciona bien sin etiqueta accionada por anotación, y esta clase de controlador es muy similar. De hecho, solo hay un método que maneja la solicitud HTTP hacia la ruta "/"
Este es el código de mi clase de controlador:
package com.mycompany.maventestwebapp;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
¿Alguien puede ayudarme a entender esto?
¡Muchas gracias!
<mvc:annotation-driven />
significa que puede definir dependencias de beans de primavera sin tener que especificar un grupo de elementos en XML o implementar una interfaz o extender una clase base. Por ejemplo, @Repository
para decir a Spring que una clase es un Dao sin tener que extender JpaDaoSupport
o alguna otra subclase de DaoSupport. De @Controller
similar, @Controller
le dice a Spring que la clase especificada contiene métodos que manejarán las solicitudes Http sin tener que implementar la interfaz del Controlador o extender una subclase que implemente el controlador.
Cuando comienza la primavera, lee su archivo de configuración XML y busca <bean
elements dentro de él si ve algo como <bean class="com.example.Foo" />
y Foo se marcó con @Controller
, sabe que la clase es un controlador y lo trata como tal. De forma predeterminada, Spring asume que todas las clases que debe administrar se definen explícitamente en el archivo beans.XML.
El escaneo de componentes con <context:component-scan base-package="com.mycompany.maventestwebapp" />
dice a la primavera que debe buscar en el classpath para todas las clases en com.mycompany.maventestweapp y mirar cada clase para ver si tiene un @Controller
, o @Repository
, o @Service
, o @Component
y si lo hace, Spring registrará la clase con la fábrica de @Component
como si hubiera escrito <bean class="..." />
en la configuración XML archivos.
En una aplicación MVC de primavera típica, encontrará que hay dos archivos de configuración de primavera, un archivo que configura el contexto de la aplicación que generalmente se inicia con el oyente de contexto Spring.
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Y un archivo de configuración de Spring MVC generalmente se inició con el servlet del distribuidor de Spring. Por ejemplo.
<servlet>
<servlet-name>main</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Spring tiene soporte para las fábricas de beans jerárquicas, por lo que en el caso de Spring MVC, el contexto del servlet del operador es un elemento secundario del contexto de la aplicación principal. Si al contexto del servlet se le pidió un bean llamado "abc" primero se verá en el contexto del servlet, si no lo encuentra allí se verá en el contexto principal, que es el contexto de la aplicación.
Los beans comunes como las fuentes de datos, la configuración de JPA, los servicios comerciales se definen en el contexto de la aplicación, mientras que la configuración específica de MVC no es el archivo de configuración asociado con el servlet.
Espero que esto ayude.
<context:component-scan base-package="" />
le dice a Spring que escanee esos paquetes para Anotaciones.
<mvc:annotation-driven>
registra un RequestMappingHanderMapping, un RequestMappingHandlerAdapter y un ExceptionHandlerExceptionResolver para admitir los métodos de control anotados como @RequestMapping, @ExceptionHandler, etc. que vienen con MVC.
Esto también habilita un servicio de conversión que admite el formato de salidas accionado por anotación así como la validación impulsada por anotación para las entradas. También habilita el soporte para @ResponseBody que puede usar para devolver datos JSON.
Puede lograr las mismas cosas utilizando la Configuración basada en Java utilizando @ComponentScan (basePackages = {"...", "..."} y @EnableWebMvc en una clase @Configuration.
Consulte la documentación 3.1 para obtener más información.
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-config