溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Springmvc框架是怎樣執(zhí)行的

發(fā)布時(shí)間:2020-06-02 16:40:48 來(lái)源:億速云 閱讀:243 作者:Leah 欄目:編程語(yǔ)言

今天小編給大家分享的是Springmvc框架的執(zhí)行流程,相信大部分人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,話(huà)不多說(shuō),一起往下看吧。

先上圖:

Springmvc框架是怎樣執(zhí)行的

下面結(jié)合源代碼和上圖來(lái)說(shuō)明:

一:發(fā)送請(qǐng)求到DispatchServlet(中央控制器)

Web.xml配置文件:

<servlet>

 <servlet-name>dispatcherServlet</servlet-name>

 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

 </servlet>

<servlet-mapping>

 <servlet-name>dispatcherServlet</servlet-name>

 <url-pattern>/</url-pattern>

</servlet-mapping>

是不是很熟悉的感覺(jué),沒(méi)錯(cuò)這里就是servlet的配置,只不過(guò)這個(gè)servlet是系統(tǒng)已經(jīng)實(shí)現(xiàn)好的中央控制器:DispatcherServlet.

二:DispatcherServlet(中央控制器)調(diào)用HandlerMapping(處理器映射器)根據(jù)請(qǐng)求url找到需要執(zhí)行的處理器(此處做了簡(jiǎn)化實(shí)際返回的是執(zhí)行鏈)

HandlerMapping是一個(gè)接口:

public interface HandlerMapping {

 。。。

 

 @Nullable

 HandlerExecutionChain getHandler(HttpServletRequest var1) throws Exception;

}

這個(gè)接口里面只有一個(gè)方法:getHandler,該方法可以通過(guò)傳入的參數(shù)請(qǐng)求對(duì)象:HttpServletRequest,得到 :HandlerExecutionChain,這里的HandlerExecutionChain里面包括了處理器對(duì)象和攔截器??梢院?jiǎn)單的理解為該方法通過(guò)request請(qǐng)求對(duì)象獲得要執(zhí)行的處理器(每種HandlerMapping實(shí)現(xiàn)類(lèi)返回的處理器不一定相同,有可能是處理器中的方法,也有可能是處理器本身)。

默認(rèn)的HandlerMapping實(shí)現(xiàn)類(lèi)是BeanNameUrlHandlerMapping,他的getHandler方法返回的是處理器類(lèi), 常用的HandlerMapping實(shí)現(xiàn)類(lèi)有:

RequestMappingHandlerMapping:采用注解方式進(jìn)行映射,使用最廣泛,也最簡(jiǎn)單,只需要在類(lèi)或方法上加上@RequestMapping()的注解就可以了,它的getHandler方法返回的是處理器類(lèi)中的方法。

@Controller

public class HelloController {

    @RequestMapping("/sayHello")

    public String sayHello(){

        System.out.println("hello");

        return "success";

    }

}

SimpleUrlHandlerMapping:采用配置文件的方式進(jìn)行映射,適用性最強(qiáng),需要在配置文件里面配置,它的getHandler方法返回的是處理器類(lèi)。

三:DispatcherServlet(中央控制器)通過(guò)HandlerAdapter(處理器適配器)調(diào)用處理器

因?yàn)椴煌腍andlerMapping實(shí)現(xiàn)類(lèi)返回的處理器格式不是固定的,所以處理請(qǐng)求時(shí)需要HandlerAdapter(處理器適配器)做適配。

public interface HandlerAdapter {

//判斷該適配器是否支持傳入的handler(處理器)

 boolean supports(Object handler);

//使用給定的handler處理請(qǐng)求,也就是執(zhí)行handler

 @Nullable

 ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object handler) throws Exception;

 

 long getLastModified(HttpServletRequest var1, Object var2);

}

HandlerAdapter也是一個(gè)接口,它里面有兩個(gè)重要的方法:

boolean supports(Object handler) 這個(gè)方法可以判斷該適配器是否支持傳入的handler(處理器)

ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object handler)throws Exception; 這個(gè)方法使用給定的handler處理請(qǐng)求,也就是執(zhí)行handler.

常用的HandlerAdapter實(shí)現(xiàn)類(lèi)是RequestMappingHandlerAdapter,它是和RequestMappingHandlerMapping配合使用的。

在spring mvc的核心配置文件中加上:<mvc:annotation-driven /> 就會(huì)自動(dòng)幫我們注冊(cè)RequestMappingHandlerMapping和RequestMappingHandlerAdapter

 

    <!-- 配置spring創(chuàng)建容器時(shí)要掃描的包 -->

    <context:component-scan   base-package="cn.xh"></context:component-scan>

    <!-- 配置視圖解析器 -->

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="prefix" value="/WEB-INF/pages/"></property>

        <property name="suffix" value=".jsp"></property>

    </bean>

 

    <mvc:annotation-driven />

 

下面是網(wǎng)上看到的一套模擬springmvc適配器的代碼:

//定義一個(gè)Adapter接口 

public interface HandlerAdapter { 

    public boolean supports(Object handler); 

    public void handle(Object handler); 

} 



//以下是三種Controller實(shí)現(xiàn) 

public interface Controller { 



} 



public class HttpController implements Controller{ 

    public void doHttpHandler(){ 

        System.out.println("http..."); 

    } 

} 



public class SimpleController implements Controller{ 

    public void doSimplerHandler(){ 

        System.out.println("simple..."); 

    } 

} 



public class AnnotationController implements Controller{ 

    public void doAnnotationHandler(){ 

        System.out.println("annotation..."); 

    } 

} 





//下面編寫(xiě)適配器類(lèi) 



public class SimpleHandlerAdapter implements HandlerAdapter { 





    public void handle(Object handler) { 

        ((SimpleController)handler).doSimplerHandler(); 

    } 



    public boolean supports(Object handler) { 

        return (handler instanceof SimpleController); 

    } 



} 





public class HttpHandlerAdapter implements HandlerAdapter { 



    public void handle(Object handler) { 

        ((HttpController)handler).doHttpHandler(); 

    } 



    public boolean supports(Object handler) { 

        return (handler instanceof HttpController); 

    } 



} 







public class AnnotationHandlerAdapter implements HandlerAdapter { 



    public void handle(Object handler) { 

        ((AnnotationController)handler).doAnnotationHandler(); 

    } 



    public boolean supports(Object handler) { 



        return (handler instanceof AnnotationController); 

    } 



} 





//模擬一個(gè)DispatcherServlet 

import java.util.ArrayList; 

import java.util.List; 





public class DispatchServlet { 



    public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();  



    public DispatchServlet(){ 

        handlerAdapters.add(new AnnotationHandlerAdapter()); 

        handlerAdapters.add(new HttpHandlerAdapter()); 

        handlerAdapters.add(new SimpleHandlerAdapter()); 

    } 





    public void doDispatch(){ 



        //此處模擬SpringMVC從request取handler的對(duì)象,僅僅new出,可以出,              

                     //不論實(shí)現(xiàn)何種Controller,適配器總能經(jīng)過(guò)適配以后得到想要的結(jié)果 

//      HttpController controller = new HttpController(); 

//      AnnotationController controller = new AnnotationController(); 

        SimpleController controller = new SimpleController(); 

        //得到對(duì)應(yīng)適配器 

        HandlerAdapter adapter = getHandler(controller); 

        //通過(guò)適配器執(zhí)行對(duì)應(yīng)的controller對(duì)應(yīng)方法 

        adapter.handle(controller); 



    } 



    public HandlerAdapter getHandler(Controller controller){ 

        for(HandlerAdapter adapter: this.handlerAdapters){ 

            if(adapter.supports(controller)){ 

                return adapter; 

            } 

        } 

        return null; 

    } 



    public static void main(String[] args){ 

        new DispatchServlet().doDispatch(); 

    } 



} 



四:執(zhí)行處理器,返回ModelAndView給中央控制器

這里的ModelAndView類(lèi)指的是執(zhí)行完處理器以后需要在視圖顯示的數(shù)據(jù)和視圖,Model數(shù)據(jù),View視圖這個(gè)名字就很清晰的表明了該類(lèi)的作用。執(zhí)行處理器后,將數(shù)據(jù)保存在ModelAndView的Model屬性中,將要顯示的視圖(通常為邏輯視圖名)保存在View屬性中,然后返回,ModelAndView類(lèi)可以將處理器和視圖渲染之間的緊密聯(lián)系解耦和。

@RequestMapping("/findModelAndView")

public ModelAndView findModelAndView(){

    System.out.println("modelAndView");

    ModelAndView md = new ModelAndView();

    User u1 = new User();

    u1.setUid(1);

    u1.setName("zhangsan");

    u1.setAge(23);

    md.addObject("user",u1);

    md.setViewName("aa");

    return md;

}

五:中央控制器調(diào)用ViewResolver(視圖解析器)根據(jù)處理器返回的ModelAndView中的邏輯視圖名為中央控制器返回一個(gè)可用的view實(shí)例。

public interface ViewResolver {

 @Nullable

 View resolveViewName(String viewName, Locale var2) throws Exception;

}

接口ViewResolver里面有一個(gè)方法:resolveViewName,可以根據(jù)邏輯視圖名viewName返回一個(gè)View實(shí)例。

public interface View {

 void render(@Nullable Map<String, ?> model, HttpServletRequest var2, HttpServletResponse var3) throws Exception;

}

View接口里面有一個(gè)方法render,可以將數(shù)據(jù)model渲染到視圖。

六:中央控制器根據(jù)View渲染視圖(將模型填充到視圖),并響應(yīng)給用戶(hù)。

以上就是Springmvc框架的執(zhí)行流程了,看完之后是否有所收獲呢?如果想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI