問(wèn)題描述
前幾天開(kāi)始研究這個(gè)Spring Hello World教程:http://viralpatel.net/blogs/spring-3-mvc-create-hello-world-application-spring-3-mvc/
Some days ago I began to study this Spring Hello World Tutorial: http://viralpatel.net/blogs/spring-3-mvc-create-hello-world-application-spring-3-mvc/
在本教程中,Spring DispatcherServlet 是使用 spring-servlet.xml 文件配置的,這個(gè):
In this tutorial Spring DispatcherServlet is configured using the spring-servlet.xml file, this one:
<?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>
在這個(gè)文件中,我使用 context:component-scan 標(biāo)簽來(lái)表示 Spring 必須掃描我的文件以搜索注解,例如,當(dāng)控制器類(lèi)發(fā)現(xiàn)一個(gè)方法被注解時(shí)通過(guò) @RequestMapping("/hello") 注釋知道該方法處理向以/hello"結(jié)尾的 URL 的 HTTP 請(qǐng)求.這很簡(jiǎn)單……
In this file I am using the context:component-scan tag to say that Spring have to scan my file searching the annotation, so for example, when the controller class finds that a method is annotated by @RequestMapping("/hello") annotation knows that this method handles the HTTP Request toward the URL ending with "/hello". This is simple...
現(xiàn)在我的疑問(wèn)與我可以在 STSEclipse 中自動(dòng)構(gòu)建的 Spring MVC 模板項(xiàng)目有關(guān).
Now my doubt is related to the Spring MVC template project that I could automatically build in STSEclipse.
當(dāng)我在 STS 中創(chuàng)建一個(gè)新的 Spring MVC 項(xiàng)目時(shí),我的 DispatcherServlet 是由一個(gè)名為 servlet-context.xml 的文件配置的,該文件包含一些類(lèi)似于上一個(gè)示例文件.
When I create a new Spring MVC project in STS I have that my DispatcherServlet is configured by a file named servlet-context.xml that contains some configuration similar to the previous example file.
在這個(gè)文件中,我還有組件掃描標(biāo)簽:
In this file, I still have the component scan tag:
<context:component-scan base-package="com.mycompany.maventestwebapp" />
但我還有另一個(gè)標(biāo)簽(看起來(lái)有類(lèi)似的任務(wù)),這個(gè):
but I have also another tag (that look like have similar task), this one:
<annotation-driven />
這兩個(gè)標(biāo)簽有什么區(qū)別?
另一個(gè)奇怪"的事情是前面的示例(不使用注釋驅(qū)動(dòng)標(biāo)簽)與 STS 使用 Spring MVC 模板項(xiàng)目創(chuàng)建的項(xiàng)目非常相似,但是如果我從其配置中刪除注釋驅(qū)動(dòng)標(biāo)簽文件項(xiàng)目不運(yùn)行并給我以下錯(cuò)誤:HTTP Status 404 -
What is the difference between these two tags?
An other "strange" thing is that the previous example (that don't use the annotation-driven tag) is very similar to the project create by STS using the Spring MVC Template project but if I delete the annotation-driven tag from its configuration file the project don't run and give me the following error: HTTP Status 404 -
在堆棧跟蹤中我有:
警告:org.springframework.web.servlet.PageNotFound - 在名為appServlet"的 DispatcherServlet 中找不到具有 URI [/maventestwebapp/] 的 HTTP 請(qǐng)求的映射
但是為什么呢?前面的例子在沒(méi)有注釋驅(qū)動(dòng)標(biāo)簽的情況下運(yùn)行良好,這個(gè)控制器類(lèi)非常相似.實(shí)際上,只有一種方法可以處理對(duì)/"路徑的 HTTP 請(qǐng)求
But why? The previous example works well without annotation-driven tag, and this controller class is very similar. In fact, there is only one method that handles HTTP request toward "/" path
這是我的控制器類(lèi)的代碼:
This is the code of my controller class:
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";
}
有人可以幫我理解這件事嗎?
Can someone help me to understand this thing?
非常感謝!
推薦答案
<mvc:annotation-driven/>
表示可以定義spring beans依賴(lài),而不必實(shí)際指定一堆XML 中的元素或?qū)崿F(xiàn)接口或擴(kuò)展基類(lèi).例如 @Repository
告訴 spring 一個(gè)類(lèi)是一個(gè) Dao,而不必?cái)U(kuò)展 JpaDaoSupport
或 DaoSupport 的一些其他子類(lèi).類(lèi)似地,@Controller
告訴 spring,指定的類(lèi)包含將處理 Http 請(qǐng)求的方法,而無(wú)需實(shí)現(xiàn) Controller 接口或擴(kuò)展實(shí)現(xiàn)控制器的子類(lèi).
<mvc:annotation-driven />
means that you can define spring beans dependencies without actually having to specify a bunch of elements in XML or implement an interface or extend a base class. For example @Repository
to tell spring that a class is a Dao without having to extend JpaDaoSupport
or some other subclass of DaoSupport. Similarly @Controller
tells spring that the class specified contains methods that will handle Http requests without you having to implement the Controller interface or extend a subclass that implements the controller.
當(dāng) spring 啟動(dòng)時(shí),它會(huì)讀取其 XML 配置文件并在其中查找 <bean
元素,如果它看到類(lèi)似 <bean class="com.example.Foo"/>
并且 Foo 被標(biāo)記為 @Controller
它知道該類(lèi)是控制器并將其視為控制器.默認(rèn)情況下,Spring 假定它應(yīng)該管理的所有類(lèi)都明確定義在 beans.XML 文件中.
When spring starts up it reads its XML configuration file and looks for <bean
elements within it if it sees something like <bean class="com.example.Foo" />
and Foo was marked up with @Controller
it knows that the class is a controller and treats it as such. By default, Spring assumes that all the classes it should manage are explicitly defined in the beans.XML file.
使用 <context:component-scan base-package="com.mycompany.maventestwebapp"/>
進(jìn)行組件掃描告訴 spring 它應(yīng)該在類(lèi)路徑中搜索 com 下的所有類(lèi).mycompany.maventestweapp 并查看每個(gè)類(lèi)以查看它是否具有 @Controller
或 @Repository
或 @Service
或 @Component
如果是,那么 Spring 將向 bean 工廠注冊(cè)該類(lèi),就像您在 XML 配置文件中鍵入 <bean class="..."/>
.
Component scanning with <context:component-scan base-package="com.mycompany.maventestwebapp" />
is telling spring that it should search the classpath for all the classes under com.mycompany.maventestweapp and look at each class to see if it has a @Controller
, or @Repository
, or @Service
, or @Component
and if it does then Spring will register the class with the bean factory as if you had typed <bean class="..." />
in the XML configuration files.
在一個(gè)典型的 Spring MVC 應(yīng)用程序中,你會(huì)發(fā)現(xiàn)有兩個(gè) Spring 配置文件,一個(gè)配置應(yīng)用程序上下文的文件通常以 Spring 上下文偵聽(tīng)器啟動(dòng).
In a typical spring MVC app you will find that there are two spring configuration files, a file that configures the application context usually started with the Spring context listener.
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Spring MVC 配置文件通常以 Spring 調(diào)度程序 servlet 啟動(dòng).例如.
And a Spring MVC configuration file usually started with the Spring dispatcher servlet. For example.
<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 支持分層 bean 工廠,因此在 Spring MVC 的情況下,調(diào)度程序 servlet 上下文是主應(yīng)用程序上下文的子級(jí).如果向 servlet 上下文詢(xún)問(wèn)名為abc"的 bean,它將首先在 servlet 上下文中查找,如果在其中找不到它,它將在父上下文中查找,即應(yīng)用程序上下文.
Spring has support for hierarchical bean factories, so in the case of the Spring MVC, the dispatcher servlet context is a child of the main application context. If the servlet context was asked for a bean called "abc" it will look in the servlet context first, if it does not find it there it will look in the parent context, which is the application context.
數(shù)據(jù)源、JPA 配置、業(yè)務(wù)服務(wù)等通用 bean 是在應(yīng)用程序上下文中定義的,而 MVC 特定配置不是與 servlet 關(guān)聯(lián)的配置文件.
Common beans such as data sources, JPA configuration, business services are defined in the application context while MVC specific configuration goes not the configuration file associated with the servlet.
希望這會(huì)有所幫助.
這篇關(guān)于Spring MVC:<context:component-scan> 之間的區(qū)別和<注釋驅(qū)動(dòng)/>標(biāo)簽?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!