問題描述
前幾天開始研究這個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 文件配置的,這個:
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>
在這個文件中,我使用 context:component-scan 標簽來表示 Spring 必須掃描我的文件以搜索注解,例如,當控制器類發現一個方法被注解時通過 @RequestMapping("/hello") 注釋知道該方法處理向以/hello"結尾的 URL 的 HTTP 請求.這很簡單……
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...
現在我的疑問與我可以在 STSEclipse 中自動構建的 Spring MVC 模板項目有關.
Now my doubt is related to the Spring MVC template project that I could automatically build in STSEclipse.
當我在 STS 中創建一個新的 Spring MVC 項目時,我的 DispatcherServlet 是由一個名為 servlet-context.xml 的文件配置的,該文件包含一些類似于上一個示例文件.
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.
在這個文件中,我還有組件掃描標簽:
In this file, I still have the component scan tag:
<context:component-scan base-package="com.mycompany.maventestwebapp" />
但我還有另一個標簽(看起來有類似的任務),這個:
but I have also another tag (that look like have similar task), this one:
<annotation-driven />
這兩個標簽有什么區別?
另一個奇怪"的事情是前面的示例(不使用注釋驅動標簽)與 STS 使用 Spring MVC 模板項目創建的項目非常相似,但是如果我從其配置中刪除注釋驅動標簽文件項目不運行并給我以下錯誤: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 請求的映射
但是為什么呢?前面的例子在沒有注釋驅動標簽的情況下運行良好,這個控制器類非常相似.實際上,只有一種方法可以處理對/"路徑的 HTTP 請求
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
這是我的控制器類的代碼:
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依賴,而不必實際指定一堆XML 中的元素或實現接口或擴展基類.例如 @Repository
告訴 spring 一個類是一個 Dao,而不必擴展 JpaDaoSupport
或 DaoSupport 的一些其他子類.類似地,@Controller
告訴 spring,指定的類包含將處理 Http 請求的方法,而無需實現 Controller 接口或擴展實現控制器的子類.
<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.
當 spring 啟動時,它會讀取其 XML 配置文件并在其中查找 <bean
元素,如果它看到類似 <bean class="com.example.Foo"/>
并且 Foo 被標記為 @Controller
它知道該類是控制器并將其視為控制器.默認情況下,Spring 假定它應該管理的所有類都明確定義在 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"/>
進行組件掃描告訴 spring 它應該在類路徑中搜索 com 下的所有類.mycompany.maventestweapp 并查看每個類以查看它是否具有 @Controller
或 @Repository
或 @Service
或 @Component
如果是,那么 Spring 將向 bean 工廠注冊該類,就像您在 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.
在一個典型的 Spring MVC 應用程序中,你會發現有兩個 Spring 配置文件,一個配置應用程序上下文的文件通常以 Spring 上下文偵聽器啟動.
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 調度程序 servlet 啟動.例如.
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 的情況下,調度程序 servlet 上下文是主應用程序上下文的子級.如果向 servlet 上下文詢問名為abc"的 bean,它將首先在 servlet 上下文中查找,如果在其中找不到它,它將在父上下文中查找,即應用程序上下文.
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.
數據源、JPA 配置、業務服務等通用 bean 是在應用程序上下文中定義的,而 MVC 特定配置不是與 servlet 關聯的配置文件.
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.
希望這會有所幫助.
這篇關于Spring MVC:<context:component-scan> 之間的區別和<注釋驅動/>標簽?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!