1. 程式人生 > >第五章構建Spring Web應用程序——SpringMVC起步

第五章構建Spring Web應用程序——SpringMVC起步

而是 ack 前端控制器 ota ring ron urn pan 處理器

跟蹤Spring MVC的請求

技術分享圖片

  註:流程:

    1)請求離開瀏覽器到達的第一站就是前端控制器,在這裏一個單例的Servlet將請求委托給應用程序的其他組件來執行實際處理。DispatcherServlet就是Spring MVC中的前端控制器(front controller)。

    2)DispatcherServlet將請求發送給Spring MVC的控制器(controller),控制器是用於處理請求的Spring組件,一個應用程序中會有一(多)個控制器。但是DispatcherServlet需要知道將請求發送給哪個控制器,所以DispatcherServlet會查詢一(多)個處理器映射

(handler Mapping)來確定下一站去哪裏。處理器映射會根據請求所攜帶的URL信息來進行決策。

    3)一旦選擇了合適的控制器,DispatcherServlet會將請求發送給選中的控制器。到了控制器,請求會卸下其負載(攜帶的用戶信息)並耐心等待控制器處理信息。實際上,設計良好的控制器本身只處理很少甚至不處理工作,而是將業務邏輯委托給一(多)個服務對象進行處理。

    4)控制器在完成邏輯處理後,會產生信息,這些信息返回給用戶並在瀏覽器上顯示。這些信息稱為模型(model),信息也會發送給一個視圖(View)。

      實際上如果采用前後端分離的話,那麽後端是不會返回視圖的,僅僅會返回json數據跟前端進行交互。

    5)控制器做的最後一步是將數據模型打包,並且標示出用於渲染輸出的視圖名。它接下來會將請求同模型和視圖名一起發給DispatcherServlet,這樣控制器就不會與特定的視圖耦合,傳遞給DispatcherServlet的視圖名並不直接表示某個特定的JSP。實際上它並不確定視圖就是jsp。相反僅僅是只傳遞一個邏輯名稱,這個名字會查找並產生真正的視圖。DispatcherServlet會使用視圖解析器將邏輯名稱轉化為一個真正的視圖。

    7)DispatcherServlet已經成功渲染了視圖,請求將交付給模型數據。請求的任務就完成了。視圖將使用模型數據渲染輸出,這個輸出會通過響應對象傳遞給客戶端。


搭建Spring MVC

  配置DispatcherServlet

    在Servlet3規範和Spring3.1的幫助下我們可以實現不使用web.xml,而是將DispatcherServlet配置在Servlet容器中。

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    //將DispatcherServlet映射到"/"
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }

    //指定配置類
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{Webconfig.class};
    }
}

  AbstractAnnotationConfigDispatcherServletInitializer剖析

  在Servlet3.0環境,容器會在類路徑中查找實現了javax.servlet.ServletContainerInitailizer接口的類。如果有的話就會用它來配置Servlet容器。

  Spring提供了這個類的實現:SpringServletContainerInitializer,這個類又會查找實現WebApplicationInitializer的類並將配置的任務交給他們。

  在Spring3.2又引入了一個WebApplicationInitializer基礎實現,這就是AbstractAnnotationConfigDispatcherServletInitializer。

  我們自己的WebAppInitializer實現了AbstractAnnotationConfigDispatcherServletInitializer,所以只要部署到Servlet3.0容器中,容器就會自動發現他,並使用它來發現Servlet上下文。

  只需要重寫其中的三個方法就ok了。

  getServletMappings(),它會將一(多)個路徑映射到DispatcherServlet。

  getRootConfigClasses():加載

  getServletConfigClasses():

  兩個應用上下文之間的關系

  DispatcherServlet與ContextLoaderListener。

  DispatcherServlet加載的上下文是當前Servlet的上下文。加載web組件的bean,如控制器、視圖解析器、以及處理器映射器等。

  而ContextLoaderListener加載的上下文是全局上下文。加載的通常是驅動應用後端的中間層或者數據層組件。

  註:DispatcherServlet是可以多實現的,每一個DispatcherServlet都有自己的上下文,就是通過getServletConfigClasses()獲取。而對於整個應用來說也有自己的上下文,這個上下文是由ContextLoaderListener進行加載的。

  AbstractAnnotationConfigDispatcherServletInitializer會同時創建DispatcherServlet與ContextLoaderListener。

  getServletConfigClasses()會返回帶有@Configuration註解的類將用來定義DispatcherServlet應用上下文的bean。

  getRootConfigClasses()會返回帶有@Configuration註解的類將用來定義ContextLoaderListener創建的應用上下文的bean。

  本例中,根配置定義在RootConfig中,DispatcherServlet的配置聲明在WebConfig中。

  啟用Spring MVC

  最簡單的SpringMVC配置(帶有@EnableWebMvc註解的類):

@Configuration
@EnableWebMvc
public class WebConfig {
}

  可以通過它,運行SpringMVC,但是還有問題需要解決。

    1)沒有視圖解析器。Spring會默認使用BeanNameView-Resolver,這個視圖解析器會查找ID與視圖名稱匹配的bean,並且查找的bean要實現View接口,他以這樣的方式解析視圖。

    2)沒有啟動組件掃描。Spring只能找到顯示聲明在配置類中的控制器。

    3)DispatcherServlet會映射為應用默認的Servlet,它會處理所以請求,包括靜態資源的請求。

  修改一下:最小但可用的SpringMVC配置。

@Configuration
//啟用SpringMVC
@EnableWebMvc
//啟用組件掃描
@ComponentScan("com.learn.spring.five.dispatcherservlet.web")
public class WebConfig extends WebMvcConfigurerAdapter{

    //配置jsp視圖解析器
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

    //配置靜態資源的處理
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

  我們添加了@ComponentScan註解,可以對對應包來查找組件。我們可以通過@Controller註解實現控制器組件。

  添加了ViewResolver bean,其實是InternalResourceViewResolver,這個視圖解析器會幫助我們查找jsp文件,且會幫我們加上前後綴。

  擴展了WebMvcConfigurerAdapter並重寫了configureDefaultServletHandling()方法,通過DefaultServletHandlerConfigurer的enable()方法,DispatcherServlet將對靜態資源的請求轉發到Servlet容器中默認的Servlet上,而不是DispatcherServlet本身處理此類方法。

  本章節聚焦於web開發,RootConfig會相對簡單:

@Configuration
@ComponentScan(basePackages = {"com"},
        excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,value = EnableWebMvc.class)
        })
public class RootConfig {
}

  模擬背景

    User(應用用戶)和state(用戶發布的狀態)。

    類似於微博的一款應用背景。

第五章構建Spring Web應用程序——SpringMVC起步