国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SpringMVC之源碼分析--ViewResolver(一)

pf_miles / 963人閱讀

摘要:概述本章開始進(jìn)入另一重要的組件,即視圖組件,處理視圖組件使用兩個(gè)主要的接口是和。接口的作用是用于處理視圖進(jìn)行渲染。延用之前的介紹流程,本章分兩部分進(jìn)行闡述啟動(dòng)初始化和請(qǐng)求處理。

概述

本章開始進(jìn)入另一重要的組件,即視圖組件,Spring MVC處理視圖組件使用兩個(gè)主要的接口是ViewResolver和View。根據(jù)名稱可知,ViewResolver即視圖解析器,其作用是把邏輯視圖名稱解析為真正的視圖,然后通過View對(duì)象進(jìn)行渲染。View接口的作用是用于處理視圖進(jìn)行渲染。

延用之前的介紹流程,本章分兩部分進(jìn)行闡述:?jiǎn)?dòng)初始化和請(qǐng)求處理。

本系列文章是基于Spring5.0.5RELEASE。

ViewResolver初始化

Spring MVC初始化視圖解析器策略與初始化其他策略一樣,其入口是DispatcherSerlvet的initStrategies(context)方法,代碼如下:

/**
 *初始化策略對(duì)象
 */
protected void initStrategies(ApplicationContext context) {
    initMultipartResolver(context);
    initLocaleResolver(context);
    initThemeResolver(context);
    initHandlerMappings(context);
    initHandlerAdapters(context);
    initHandlerExceptionResolvers(context);
    initRequestToViewNameTranslator(context);
    // 初始化視圖解析器ViewResolver
    initViewResolvers(context);
    initFlashMapManager(context);
}

看過之前文章的可以了解,此方法是Spring MVC初始化策略組件的入口。針對(duì)視圖解析器組件,調(diào)用initViewResolver(context)方法,加載視圖處理策略,該方法源碼如下:

private void initViewResolvers(ApplicationContext context) {
    // viewResolvers是視圖解析器集合,接收到用戶請(qǐng)求時(shí),從該屬性變量中獲取到Spring MVC使用的視圖解析器
    this.viewResolvers = null;
    // 是否從Spring上下文中加載ViewResolver,detectAllViewResolvers屬性變量默認(rèn)為true,可在web部署描述文件中修改
    if (this.detectAllViewResolvers) {
        // Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
        // 按接口類型ViewResolver查找全部
        // key為bean的id(name),value為bean的class對(duì)象
        Map matchingBeans =
                BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
        if (!matchingBeans.isEmpty()) {
            this.viewResolvers = new ArrayList<>(matchingBeans.values());
            // We keep ViewResolvers in sorted order.
            // 對(duì)ViewResolver進(jìn)行排序,通過Ordered接口實(shí)現(xiàn)
            AnnotationAwareOrderComparator.sort(this.viewResolvers);
        }
    }
    else { 
        try {
            // 從Spring上下文中加載指定名字為"viewResolver"的bean,作為視圖解析器
            ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);
            this.viewResolvers = Collections.singletonList(vr);
        }
        catch (NoSuchBeanDefinitionException ex) {
            // Ignore, we"ll add a default ViewResolver later.
        }
    }

    // Ensure we have at least one ViewResolver, by registering
    // a default ViewResolver if no other resolvers are found.
    // 為了確保至少有一個(gè)ViewResolver視圖解析器,Spring MVC配置了默認(rèn)的ViewResolver
    // 在DispatcherServlet.properties文件中定義,默認(rèn)為InternalResourceViewResolver
    if (this.viewResolvers == null) {
        this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
        if (logger.isDebugEnabled()) {
            logger.debug("No ViewResolvers found in servlet "" + getServletName() + "": using default");
        }
    }
}

至此,Spring MVC即完成加載初始化ViewResolver視圖解析器,即Spring MVC以具備解析處理邏輯視圖名稱的能力。

ViewResolver使用

ViewResolver的使用是指用戶發(fā)起請(qǐng)求到Spring,Spring MVC經(jīng)過HandlerMapping查找處理的handler,然后通過HandlerAdapter進(jìn)行適配后處理用戶請(qǐng)求,返回ModelAndView,最后使用ViewResolver對(duì)ModelAndView進(jìn)行解析,即把邏輯視圖名解析為真正的視圖對(duì)象,由視圖對(duì)象進(jìn)行渲染的過程。

用戶的請(qǐng)求處理流程由DispatcherServlet的doDispatcher(request,response)方法進(jìn)行控制,主要代碼如下:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    ... ...
    // 找到請(qǐng)求對(duì)應(yīng)的handler
    mappedHandler = getHandler(processedRequest);
    ... ...
    // 找到對(duì)應(yīng)handler的適配器
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    ... ...
    // 執(zhí)行用戶請(qǐng)求的攔截器前置處理方法
    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
        return;
    }
    // 調(diào)用實(shí)際的handler處理方法
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    ... ...
    // 設(shè)置默認(rèn)的邏輯視圖名稱
    // 如果handler返回null或者ViewName屬性為null時(shí),Spring進(jìn)行取視圖規(guī)則為:前綴+url+后綴
    // 比如訪問url為:http://localhost:8086/test,前綴配置/WEB-INF/jsp,后綴配置為.jsp,那么最終查找的是:/WEB-INF/jsp/test.jsp
    applyDefaultViewName(processedRequest, mv);
    // 執(zhí)行用戶請(qǐng)求的攔截器后置處理方法
    mappedHandler.applyPostHandle(processedRequest, response, mv);
    ... ...
    // 
    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}

/*
 *處理結(jié)果
 */
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
        @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
        @Nullable Exception exception) throws Exception {

    boolean errorView = false;
    // 異常處理
    if (exception != null) {
        if (exception instanceof ModelAndViewDefiningException) {
            logger.debug("ModelAndViewDefiningException encountered", exception);
            mv = ((ModelAndViewDefiningException) exception).getModelAndView();
        }
        else {
            Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
            mv = processHandlerException(request, response, handler, exception);
            errorView = (mv != null);
        }
    }

    // Did the handler return a view to render?
    // 調(diào)用render方法
    if (mv != null && !mv.wasCleared()) {
        render(mv, request, response);
        if (errorView) {
            WebUtils.clearErrorRequestAttributes(request);
        }
    }
    else {
        if (logger.isDebugEnabled()) {
            logger.debug("Null ModelAndView returned to DispatcherServlet with name "" + getServletName() +
                    "": assuming HandlerAdapter completed request handling");
        }
    }

    if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
        // Concurrent handling started during a forward
        return;
    }

    if (mappedHandler != null) {
        mappedHandler.triggerAfterCompletion(request, response, null);
    }
}

/*
 *渲染ModelAndView
 */
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
    // Determine locale for request and apply it to the response.
    Locale locale =
            (this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale());
    response.setLocale(locale);

    View view;
    // 獲取邏輯視圖名稱
    String viewName = mv.getViewName();
    if (viewName != null) {
        // We need to resolve the view name.
        // 根據(jù)邏輯視圖名解析視圖,返回View對(duì)象
        // 此處是視圖解析器使用入口,見下面的方法
        view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
        if (view == null) {
            throw new ServletException("Could not resolve view with name "" + mv.getViewName() +
                    "" in servlet with name "" + getServletName() + """);
        }
    }
    else {
        // No need to lookup: the ModelAndView object contains the actual View object.
        view = mv.getView();
        if (view == null) {
            throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
                    "View object in servlet with name "" + getServletName() + """);
        }
    }

    // Delegate to the View object for rendering.
    if (logger.isDebugEnabled()) {
        logger.debug("Rendering view [" + view + "] in DispatcherServlet with name "" + getServletName() + """);
    }
    try {
        if (mv.getStatus() != null) {
            response.setStatus(mv.getStatus().value());
        }
        // 調(diào)用View的render方法進(jìn)行視圖渲染
        view.render(mv.getModelInternal(), request, response);
    }
    catch (Exception ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name "" +
                    getServletName() + """, ex);
        }
        throw ex;
    }
}

@Nullable
protected View resolveViewName(String viewName, @Nullable Map model,
        Locale locale, HttpServletRequest request) throws Exception {

    if (this.viewResolvers != null) {
        for (ViewResolver viewResolver : this.viewResolvers) {
            // 調(diào)用ViewResovler接口入口方法
            View view = viewResolver.resolveViewName(viewName, locale);
            if (view != null) {
                return view;
            }
        }
    }
    return null;
}
總結(jié)

本章概述了Spring MVC加載視圖解析器策略,并且找到了ViewResolver的入口方法,下面的章節(jié)繼續(xù)學(xué)習(xí)ViewResolver接口的實(shí)現(xiàn)類。

最后創(chuàng)建了qq群方便大家交流,可掃描加入,同時(shí)也可加我qq:276420284,共同學(xué)習(xí)、共同進(jìn)步,謝謝!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/69637.html

相關(guān)文章

  • SpringMVC源碼分析--ViewResolver(三)

    摘要:概述本節(jié)學(xué)習(xí)下的功能,簡(jiǎn)單來說,該類的作用就是把多個(gè)視圖解析器進(jìn)行組裝,內(nèi)部使用存儲(chǔ)配置使用的視圖解析器。總結(jié)本章介紹了類,根據(jù)測(cè)試,了解到屬性不影響中配置使用的視圖解析器順序。 概述 本節(jié)學(xué)習(xí)下ViewResolverComposite的功能,簡(jiǎn)單來說,該類的作用就是把多個(gè)ViewResolver視圖解析器進(jìn)行組裝,內(nèi)部使用list存儲(chǔ)配置使用的視圖解析器。 本系列文章是基于Spri...

    fox_soyoung 評(píng)論0 收藏0
  • SpringMVC源碼分析--ViewResolver(二)

    摘要:概述上篇學(xué)習(xí)了視圖解析器作用及處理流程,為我們提供了豐富的視圖解析器見下圖本系列文章是基于。該視圖解析器是根據(jù)處理器返回的邏輯視圖名稱,在應(yīng)用上下文中查找該名稱的視圖對(duì)象視圖對(duì)象就是的對(duì)象。 概述 上篇學(xué)習(xí)了Spring MVC ViewResolver視圖解析器作用及處理流程,Spring為我們提供了豐富的視圖解析器(見下圖):showImg(https://segmentfault...

    jas0n 評(píng)論0 收藏0
  • SpringMVC源碼分析--ViewResolver(四)

    摘要:概述本章繼續(xù)學(xué)習(xí)另一個(gè)實(shí)現(xiàn)類解析器,該類的主要作用是根據(jù)同一請(qǐng)求的某些策略,選擇對(duì)應(yīng)的進(jìn)行渲染。可以把理解為適配器,對(duì)不同類型進(jìn)行適配。值得注意的是處理的為同一個(gè)。本系列文章是基于。實(shí)戰(zhàn)需求目標(biāo)實(shí)現(xiàn)后綴名或參數(shù)控制,顯示不同的視圖。 概述 本章繼續(xù)學(xué)習(xí)ViewResolver另一個(gè)實(shí)現(xiàn)類ContentNegotiatingViewResolver解析器,該類的主要作用是根據(jù)同一請(qǐng)求的某...

    jcc 評(píng)論0 收藏0
  • SpringMVC源碼分析--ViewResolver(六)

    摘要:與一樣,該類繼承抽象類,并且通過外部的屬性文件定義邏輯視圖名稱與真正的視圖對(duì)象的關(guān)系,屬性文件默認(rèn)是下的,可以通過或?qū)傩詠碇付?,該屬性指的是文件的基名稱,也就是說以屬性值開頭的屬性文件。 概述 本章再學(xué)習(xí)另外兩個(gè)ViewResolver,分別是XmlViewResolver和ResourceBundleViewResolver,從功能上說,這兩個(gè)視圖解析器都是從外部資源文件中查找視圖V...

    alighters 評(píng)論0 收藏0
  • SpringMVC源碼分析--ViewResolver(五)

    摘要:此解析器與差不多,更改下配置文件中的類全路徑即可。總結(jié)本章介紹了以及三個(gè)視圖解析器。這部分內(nèi)容有點(diǎn)兒多,我會(huì)盡快結(jié)束。 概述 通過上幾篇的學(xué)習(xí),我們分析了并試驗(yàn)了ViewResolverComposite、BeanNameViewResolver和ContentNegotiatingViewResolver,這三個(gè)類都直接實(shí)現(xiàn)ViewResolver接口。Spring MVC提供了很多...

    klinson 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

pf_miles

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<