爲啥要說這兩個註解的區別,由於<mvc:annotation-driven >和<context:component-scan>放置的位置出錯,可能就會致使項目出現404的錯誤。程序即不提示出錯,控制檯也不打印錯誤,這樣很難排除錯誤。因此頗有必要說明這兩個註解的區別。web
2.詳解ajax
首先咱們須要瞭解springMVC的原理,:spring
運行步驟:json
一、 首先用戶發送請求http://localhost:9080/springmvc-chapter2/hello——>web容器,web容器根據「/hello」路徑映射到DispatcherServlet(url-pattern爲/)進行處理;mvc
二、 DispatcherServlet——>BeanNameUrlHandlerMapping進行請求處處理的映射,BeanNameUrlHandlerMapping將「/hello」路徑直接映射到名字爲「/hello」的Bean進行處理,即HelloWorldController,BeanNameUrlHandlerMapping將其包裝爲HandlerExecutionChain(只包括HelloWorldController處理器,沒有攔截器);app
三、 DispatcherServlet——> SimpleControllerHandlerAdapter,SimpleControllerHandlerAdapter將HandlerExecutionChain中的處理器(HelloWorldController)適配爲SimpleControllerHandlerAdapter;jsp
四、 SimpleControllerHandlerAdapter——> HelloWorldController處理器功能處理方法的調用,SimpleControllerHandlerAdapter將會調用處理器的handleRequest方法進行功能處理,該處理方法返回一個ModelAndView給DispatcherServlet;單元測試
五、 hello(ModelAndView的邏輯視圖名)——>InternalResourceViewResolver, InternalResourceViewResolver使用JstlView,具體視圖頁面在/WEB-INF/jsp/hello.jsp;測試
六、 JstlView(/WEB-INF/jsp/hello.jsp)——>渲染,將在處理器傳入的模型數據(message=HelloWorld!)url
而<mvc:annotation-driven /> 會自動註冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean, MVC爲@Controllers分發請求所必須的。
並提供了:數據綁定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,讀寫XML的支持(JAXB),讀寫JSON的支持(Jackson)——這個是最主要的。後面,咱們處理響應ajax請求時,就使用到了對json的支持。後面,對action寫JUnit單元測試時,要從spring IOC容器中取DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,來完成測試,取的時候要知道是<mvc:annotation-driven />這一句註冊的這兩個bean。<mvc:interceptors/>會爲每個HandlerMapping,注入一個攔截器。總有一個HandlerMapping是能夠找處處理器的,最多也只找到一個處理器,因此這個攔截器總會被執行的。起到了總攔截器的做用。
@Controller
public class TestController {
//每個Springmvc
@RequestMapping(value = "/test/springmvc.do")
public String test(String name){
System.out.println();
return "";
}
若是直接在配置文件下只有<scan>註解,或者<mvc>註解配置在<scan>後面,這樣是會致使404的問題。同時就算<mvc>放在<scan>也是報404的。
解決方法:
@Controller
public class TestController {
//每個Springmvc
@RequestMapping(value = "/test/springmvc.do")
public @Requestbody String test(String name){
System.out.println();
return "";
}
須要在方法加上@Requestbody 註解,同時<mvc>,須要配置在<scan>前面。
爲何呢?由於根據上面的<mvc:annotation-driven />解釋,主要提供數據支持。
爲了深刻 <mvc:annotation-driven />的註解 ,提供了加載類,以下所示:
RequestMappingHandlerMapping
BeanNameUrlHandlerMapping
RequestMappingHandlerAdapter
HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver
上面幾個Bean實例。這幾個類都是用來作什麼的呢?
前兩個是HandlerMapping接口的實現類,用來處理請求映射的。其中第一個是處理@RequestMapping註解的。第二個會將controller類的名字映射爲請求url。
中間三個是用來處理請求的。具體點說就是肯定調用哪一個controller的哪一個方法來處理當前請求。第一個處理@Controller註解的處理器,支持自定義方法參數和返回值(很酷)。第二個是處理繼承HttpRequestHandler的處理器。第三個處理繼承自Controller接口的處理器。
而 <context:component-scan>,在使用註解(@Component,@Repository,@Service,@Controller)配置的狀況下,系統啓動時會被自動掃描,並添加到bean工廠中去(省去了配置文件中寫bean定義了),另外三個分別表示MVC三層模式中不一樣層中的組件,他們都是被@Component標記的,因此也會被自動掃描。
繼而言之:
<context:component-scan/>標籤是告訴Spring 來掃描指定包下的類,並註冊被@Component,@Controller,@Service,@Repository等註解標記的組件。
而<mvc:annotation-scan/>是告知Spring,咱們啓用註解驅動。而後Spring會自動爲咱們註冊上面說到的幾個Bean到工廠中,來處理咱們的請求。