最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringMVC的處理器適配器-HandlerAdapter的用法及說(shuō)明

 更新時(shí)間:2023年12月26日 15:02:40   作者:huangyaa729  
這篇文章主要介紹了SpringMVC的處理器適配器-HandlerAdapter的用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

SpringMVC處理器適配器HandlerAdapter用法

如題:

今天看spring源碼解析這本書時(shí),看到了這個(gè)地方,對(duì)于不同HandlerAdapter的使用場(chǎng)景有的困惑,主要還是沒見過(guò),因?yàn)榇蠖鄶?shù)面向的Controller類型的HandlerAdapter;

HandlerAdapter目前最常見的主要為

1、SimpleControllerHandlerAdapter、HttpRequestHandlerAdapter 、AnnotationMethodHandlerAdapter (已過(guò)時(shí)),這三個(gè)是默認(rèn)的;如果沒有指明新的適配器時(shí),會(huì)從這三個(gè)中間選擇;

2、SimpleServletHandlerAdapter目前很少用到,也不是默認(rèn)的適配器;

3、RequestMappingHandlerAdapter這個(gè)應(yīng)該是目前springMVC主要采用的,針對(duì)方法級(jí)的映射匹配處理。

由HandlerAdapter的實(shí)現(xiàn)類可知:映射匹配的處理器handler包括三個(gè)類型Controller、HttpRequestHandler、Servlet,但后兩個(gè)的應(yīng)用場(chǎng)景與使用方式我卻沒有見到過(guò),經(jīng)過(guò)一番查找,特做一個(gè)總結(jié)以供以后參考:

1、SimpleControllerHandlerAdapter主要是針對(duì)實(shí)現(xiàn)Controller接口的handler進(jìn)行適配,配置方式在書中可見;

2、SimpleServletHandlerAdapter主要是針對(duì)實(shí)現(xiàn)Servlet接口的handler進(jìn)行適配,配置方式跟普通的Controller類似,如下所示:

spring配置文件中bean的配置如下:

/** 采用BeanNameUrlHandlerMapping類進(jìn)行路徑映射匹配**/
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
 <bean name="/demo.do" class="com.demo.DemoServlet"/>  

對(duì)應(yīng)的Bean實(shí)現(xiàn)類為

public class DemoServlet extends HttpServlet{  
.......
}

3、HttpRequestHandlerAdapter 主要是針對(duì)實(shí)現(xiàn)HttpRequestHandler接口的handler進(jìn)行適配;

HTTP請(qǐng)求處理器適配器僅僅支持對(duì)HTTP請(qǐng)求處理器的適配。它簡(jiǎn)單的將HTTP請(qǐng)求對(duì)象和響應(yīng)對(duì)象傳遞給HTTP請(qǐng)求處理器的實(shí)現(xiàn),它并不需要返回值。它主要應(yīng)用在基于HTTP的遠(yuǎn)程調(diào)用的實(shí)現(xiàn)上。

配置應(yīng)該與上述相同,從SpringMvc自帶的實(shí)現(xiàn)類來(lái)說(shuō),主要用于轉(zhuǎn)發(fā)或者靜態(tài)資源的加載,對(duì)應(yīng)的實(shí)現(xiàn)類為DefaultServletHttpRequestHandler和ResourceHttpRequestHandler

淺談HandlerAdapter

HandlerAdapter顧名思義就是一個(gè)適配器,(肯定也采用了適配器模式這里不做過(guò)多的解釋),那么它的主要作用是什么呢?

HandlerMapping存儲(chǔ)了所有都請(qǐng)求映射,請(qǐng)求過(guò)來(lái)找到相應(yīng)的請(qǐng)求映射后,返回給我們一個(gè)Handler

看這里的代碼:

@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    if (this.handlerMappings != null) {
        Iterator var2 = this.handlerMappings.iterator();

        while(var2.hasNext()) {
            HandlerMapping mapping = (HandlerMapping)var2.next();
            HandlerExecutionChain handler = mapping.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
    }

    return null;
}

這里是DispacherServlet的核心控制方法。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
 
        try {
            try {
                ModelAndView mv = null;
                Object dispatchException = null;
 
                try {
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }
 
                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = HttpMethod.GET.matches(method);
                    if (isGet || HttpMethod.HEAD.matches(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }
 
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
 
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }
 
                    this.applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }
 
                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
            } catch (Exception var22) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
            } catch (Throwable var23) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
            }
 
        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }
 
        }
    }

我們拿到Handler之后呢?

接著代碼往下走我們可以看到這樣一行代碼

HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

這一步就是講我們的Handler進(jìn)行一個(gè)HandlerAdapter的適配解析,我們繼續(xù)代碼跟進(jìn)

public interface HandlerAdapter {
    //如果當(dāng)前支持當(dāng)前handler就執(zhí)行handler方法
    boolean supports(Object handler);
 
    @Nullable
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
 
    /** @deprecated */
    @Deprecated
    long getLastModified(HttpServletRequest request, Object handler);
}

我們知道它采用的適配器模式

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    if (this.handlerAdapters != null) {
        Iterator var2 = this.handlerAdapters.iterator();

        while(var2.hasNext()) {
            HandlerAdapter adapter = (HandlerAdapter)var2.next();
            if (adapter.supports(handler)) {
                return adapter;
            }
        }
    }

    throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}

DispacherServlet中這個(gè)方法,就是一個(gè)迭代器,給handler找一個(gè)適配器,那這一步到底是要做什么呢?

在HandlerAdapter中有四個(gè)實(shí)現(xiàn)類,分別處理不同Handler我們看一下我們最常用的HttpRequestHandlerAdapter

public boolean supports(Object handler) {
    return handler instanceof HttpRequestHandler;
}

里面就是去判斷了,當(dāng)前handler是不是HttpRequestHandler類型,其實(shí)在我們確認(rèn)號(hào)類型的時(shí)候,handler經(jīng)過(guò)RequestMappingHandlerMapping?,返回的就已經(jīng)是這個(gè)類型的了。

找到適配器之后啊,就是開始參數(shù)解析了

String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
    if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
        return;
    }
}

核心在這里,利用的HandlerAdapter,也就是剛才找到的適配器,和目標(biāo)方法傳進(jìn)去,執(zhí)行目標(biāo)方法。?

執(zhí)行完上面代碼,就是判斷了一下是不是get請(qǐng)求,HEAD這個(gè)不是由我們 去處理的。

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

上面這行代碼去執(zhí)行的目標(biāo)方法。

到這里基本是完成了HandlerAdapter的一個(gè)準(zhǔn)備工作,找到適配的HandlerAdapter之后,還要進(jìn)行相應(yīng)的參數(shù)解析啊。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • JVM中如何做到STW使程序暫停

    JVM中如何做到STW使程序暫停

    STW,即Stop The World,這篇文章來(lái)為大家詳細(xì)介紹了JVM中是如何做到STW使程序暫停的原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-01-01
  • Java Caffeine 高性能緩存庫(kù)詳解與使用案例詳解

    Java Caffeine 高性能緩存庫(kù)詳解與使用案例詳解

    Caffeine是Java生態(tài)中最先進(jìn)的本地緩存庫(kù),其 高性能、低延遲 的設(shè)計(jì)使其成為現(xiàn)代應(yīng)用的首選,通過(guò)靈活的配置和強(qiáng)大的統(tǒng)計(jì)功能,開發(fā)者可以輕松實(shí)現(xiàn)高效的緩存策略,顯著提升系統(tǒng)性能,本文介紹Java Caffeine高性能緩存庫(kù)詳解與使用案例,感興趣的朋友一起看看吧
    2025-10-10
  • springboot項(xiàng)目打包的可執(zhí)行jar運(yùn)行報(bào)錯(cuò)問(wèn)題及解決

    springboot項(xiàng)目打包的可執(zhí)行jar運(yùn)行報(bào)錯(cuò)問(wèn)題及解決

    本文介紹了SpringBoot項(xiàng)目打包成可執(zhí)行jar文件后無(wú)法使用java-jar命令啟動(dòng)的問(wèn)題及解決方法,主要是需要在pom.xml文件中添加spring-boot-maven-plugin插件,以便生成正確的MANIFEST.MF文件
    2026-04-04
  • Java中隨機(jī)數(shù)生成的代碼實(shí)現(xiàn)

    Java中隨機(jī)數(shù)生成的代碼實(shí)現(xiàn)

    在編程中,隨機(jī)數(shù)生成是一個(gè)常見的需求,無(wú)論是模擬數(shù)據(jù)、游戲開發(fā)、測(cè)試用例生成,還是簡(jiǎn)單的抽獎(jiǎng)邏輯,都可能需要隨機(jī)數(shù),Java提供了多種生成隨機(jī)數(shù)的方式,本文將通過(guò)兩個(gè)實(shí)際案例,詳細(xì)介紹如何在Java中生成隨機(jī)數(shù),需要的朋友可以參考下
    2025-07-07
  • SpringBoot Admin與Prometheus集成監(jiān)控

    SpringBoot Admin與Prometheus集成監(jiān)控

    本文深入探討Spring Boot Admin與Prometheus的集成監(jiān)控方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-01-01
  • 使用@PathVariable時(shí)候無(wú)法將參數(shù)映射到變量中的解決

    使用@PathVariable時(shí)候無(wú)法將參數(shù)映射到變量中的解決

    這篇文章主要介紹了使用@PathVariable時(shí)候無(wú)法將參數(shù)映射到變量中的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java正則表達(dá)式API邊界匹配

    Java正則表達(dá)式API邊界匹配

    這篇文章主要介紹了Java正則表達(dá)式API邊界匹配,文章圍繞主題展開相應(yīng)的相關(guān)資料,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-06-06
  • Java中Json解析的方法分析

    Java中Json解析的方法分析

    這篇文章主要介紹了Java中Json解析的方法,結(jié)合實(shí)例形式分析了java針對(duì)json格式數(shù)據(jù)的解析實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-05-05
  • Spring的InitializingBean接口解析

    Spring的InitializingBean接口解析

    這篇文章主要介紹了Spring的InitializingBean接口解析,InitializingBean是spring為bean的初始化提供了一種新的方式,里面只有一個(gè)方法afterPropertiesSet,作用就是實(shí)現(xiàn)這個(gè)接口或者實(shí)現(xiàn)了繼承InitializingBean的方法的bean都要執(zhí)行這個(gè)方法,需要的朋友可以參考下
    2024-02-02
  • Spring?Security?OAuth?Client配置加載源碼解析

    Spring?Security?OAuth?Client配置加載源碼解析

    這篇文章主要為大家介紹了Spring?Security?OAuth?Client配置加載源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07

最新評(píng)論

清流县| 拜城县| 射洪县| 兴化市| 鹰潭市| 彝良县| 贵定县| 清远市| 堆龙德庆县| 桓仁| 黑河市| 望江县| 石楼县| 馆陶县| 上饶市| 康保县| 黄龙县| 禄丰县| 菏泽市| 连城县| 尉犁县| 江口县| 东台市| 西畴县| 青冈县| 雷州市| 汶上县| 吉安市| 平利县| 桐城市| 南充市| 五台县| 淮滨县| 武乡县| 庆阳市| 西昌市| 栾城县| 滁州市| 永兴县| 平定县| 定南县|