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

SpringMVC中的DispatcherServlet結(jié)構(gòu)和初始化詳解

 更新時間:2024年01月05日 08:34:36   作者:it_lihongmin  
這篇文章主要介紹了SpringMVC中的DispatcherServlet結(jié)構(gòu)和初始化詳解,SpringMVC中Spring容器的關(guān)系是通過監(jiān)聽方式啟動的,那么Spring與Servlet的Web容器(如:Tomcat、jetty)的關(guān)系則是通過DispatcherServlet進行關(guān)聯(lián),需要的朋友可以參考下

前言

SpringMVC中Spring容器的關(guān)系是通過監(jiān)聽方式啟動的。

那么Spring(或者說SpringMVC)與Servlet的Web容器(如:Tomcat、jetty)的關(guān)系則是通過DispatcherServlet進行關(guān)聯(lián)。

在Web容器看,DispatcherServlet就是同一普通的Servlet,從Spring看是與Web的關(guān)聯(lián),會將所有的請求轉(zhuǎn)發(fā)到該控制器。

1、DispatcherServlet結(jié)構(gòu)

從層級能看出其頂層實現(xiàn)了Servlet和ServletConfig接口,由于Web容器只認識Servlet,而Spring只認識Bean,所以DispatcherServlet既是請求轉(zhuǎn)發(fā)和返回視圖解析控制中心,更是web與Spring的適配器,從其父子結(jié)構(gòu)層級就能看出,慢慢的從Servlet適配到Bean的過程。

1)、GenericServlet

GenericServlet實現(xiàn)了Servlet、ServletConfig接口,也實現(xiàn)了所有未實現(xiàn)的方法。主要是config相關(guān),init和service方法。

2)、HttpServlet

HttpServlet主要定義了Http協(xié)議相關(guān)的請求方法,以及Last-ModifiedIf-Modified-Since相關(guān)參數(shù)的處理。

3)、HttpServletBean

HttpServletBean除了繼承自HttpServlet,還實現(xiàn)了EnvironmentCapable和EnvironmentAware接口,處理Spring Environment相關(guān),之前分析過。

4)、FrameworkServlet

FrameworkServlet實現(xiàn)了接口ApplicationContextAware,注入了ApplicationContext,以及contextConfigLocation配置。

5)、DispatcherServlet

DispatcherServlet作為整個MVC的控制器,那么請求該轉(zhuǎn)發(fā)到哪個Controller,返回的model會該使用哪個視圖返回(視圖解析器進行解析)。

都需要在這里進行完成,所以初始化時需要使用到Spring MVC的九大件。

初始化時使用了策略模式初始化九大件

2、DispatcherServlet初始化(九大件的加載和初始化)

web容器啟動時會加載配置的DispatcherServlet,則會調(diào)用其init方法,在GenericServlet中實現(xiàn),如下:

@Override
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

設(shè)置了ServletConfig值,并且調(diào)用了自定義無參空方法init,在子類HttpServletBean中實現(xiàn)。

public final void init() throws ServletException {
    // 解析init-param參數(shù),并封裝成ServletConfigPropertyValues
    PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
    if (!pvs.isEmpty()) {
        try {
            BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
            ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
            bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
            initBeanWrapper(bw);
            bw.setPropertyValues(pvs, true);
        }
        catch (BeansException ex) {
            throw ex;
        }
    }
 
    // Let subclasses do whatever initialization they like.
    initServletBean();
}

在初始化方法之前,允許init-param通過addRequiredProperty方法添加到requiredProperties屬性中的配置,以Bean的形式進行加載。主要的方法初始化方法是調(diào)用本類的空方法initServletBean,在下層子類FrameworkServlet中實現(xiàn)

@Override
protected final void initServletBean() throws ServletException {
    // 省略日志打印和,try catch部分的代碼
    this.webApplicationContext = initWebApplicationContext();
    // 留給子類實現(xiàn),子類DispatcherServlet沒有進行實現(xiàn)
    initFrameworkServlet();
}
protected WebApplicationContext initWebApplicationContext() {
    WebApplicationContext rootContext =
            WebApplicationContextUtils.getWebApplicationContext(getServletContext());
    WebApplicationContext wac = null;
 
    if (this.webApplicationContext != null) {
        // A context instance was injected at construction time -> use it
        wac = this.webApplicationContext;
        if (wac instanceof ConfigurableWebApplicationContext) {
            ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
            if (!cwac.isActive()) {
                // The context has not yet been refreshed -> provide services such as
                // setting the parent context, setting the application context id, etc
                if (cwac.getParent() == null) {
                    // The context instance was injected without an explicit parent -> set
                    // the root application context (if any; may be null) as the parent
                    cwac.setParent(rootContext);
                }
                configureAndRefreshWebApplicationContext(cwac);
            }
        }
    }
    if (wac == null) {
        // No context instance was injected at construction time -> see if one
        // has been registered in the servlet context. If one exists, it is assumed
        // that the parent context (if any) has already been set and that the
        // user has performed any initialization such as setting the context id
        wac = findWebApplicationContext();
    }
    if (wac == null) {
        // 確保Spring容器創(chuàng)建并且唯一,所以無論ContextLoaderListener是否啟動和refresh
        wac = createWebApplicationContext(rootContext);
    }
 
    if (!this.refreshEventReceived) {
        // Either the context is not a ConfigurableApplicationContext with refresh
        // support or the context injected at construction time had already been
        // refreshed -> trigger initial onRefresh manually here.
        synchronized (this.onRefreshMonitor) {
            onRefresh(wac);
        }
    }
 
    if (this.publishContext) {
        // 將Spring的WebApplicationContext容器,設(shè)置到Web容器中
        String attrName = getServletContextAttributeName();
        getServletContext().setAttribute(attrName, wac);
    }
 
    return wac;
}

無論監(jiān)聽是否啟動Spring容器執(zhí)行refresh方法,這里都會進行檢查啟動。

并將啟動的Spring容器,設(shè)置到web容器中,所以當(dāng)啟動完成后兩個容器中就是你中有我,我中有你的狀態(tài)。

Spring MVC的初始化會同步鎖synchronized(onRefreshMonitor)保證下初始化,在子類層級DispatcherServlet中完成:

@Override
protected void onRefresh(ApplicationContext context) {
    initStrategies(context);
}

使用策略模式初始化九大件,為后續(xù)請求調(diào)用,視圖解析等做準備。

protected void initStrategies(ApplicationContext context) {
    // 文件上傳
    initMultipartResolver(context);
    // i18n相關(guān)解析器
    initLocaleResolver(context);
    // 主題解析器(一種主題就是一類網(wǎng)頁風(fēng)格)
    initThemeResolver(context);
    // 請求映射
    initHandlerMappings(context);
    // 適配器,后面請求轉(zhuǎn)發(fā)的Controller會專門分析
    initHandlerAdapters(context);
    // 操作異常的解析處理(中途發(fā)送異常該調(diào)整到哪里)
    initHandlerExceptionResolvers(context);
    // 請求的Controller沒有返回View時,該如何解析
    initRequestToViewNameTranslator(context);
    // 視圖解析器(ModelAndView中的view字符串怎么進行解析)
    initViewResolvers(context);
    // 請求屬性(參數(shù))管理器,主要用于重定向等情況時獲取屬性,比如post重定向到get
    initFlashMapManager(context);
}

九大件的處理方式大致相同,只是定義的Bean名稱和調(diào)用getBean的類型不同而已,比如上傳文件,如下:

private void initMultipartResolver(ApplicationContext context) {
    // 省略日志打印和try catch的代碼
    this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
}

主要看初始化的什么類型,是在靜態(tài)代碼塊的策略模式中加載初始化(DispatcherServlet.properties),如下:

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
 
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
 
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
	org.springframework.web.servlet.function.support.RouterFunctionMapping
 
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
	org.springframework.web.servlet.function.support.HandlerFunctionAdapter
 
 
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
 
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
 
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
 
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

到此這篇關(guān)于SpringMVC中的DispatcherServlet結(jié)構(gòu)和初始化詳解的文章就介紹到這了,更多相關(guān)DispatcherServlet結(jié)構(gòu)和初始化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 用Java打造簡易計算器的實現(xiàn)步驟

    用Java打造簡易計算器的實現(xiàn)步驟

    這篇文章主要介紹了如何設(shè)計和實現(xiàn)一個簡單的Java命令行計算器程序,該程序能夠執(zhí)行基本的數(shù)學(xué)運算(加、減、乘、除),文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-01-01
  • Java線程池用法實戰(zhàn)案例分析

    Java線程池用法實戰(zhàn)案例分析

    這篇文章主要介紹了Java線程池用法,結(jié)合具體案例形式分析了java線程池創(chuàng)建、使用、終止等相關(guān)操作技巧與使用注意事項,需要的朋友可以參考下
    2019-10-10
  • Java中的Cookie和Session詳細解析

    Java中的Cookie和Session詳細解析

    這篇文章主要介紹了Java中的Cookie和Session詳細解析,客戶端會話技術(shù),服務(wù)端給客戶端的數(shù)據(jù),存儲于客戶端(瀏覽器),由于是保存在客戶端上的,所以存在安全問題,需要的朋友可以參考下
    2024-01-01
  • Java游戲開發(fā)之俄羅斯方塊的實現(xiàn)

    Java游戲開發(fā)之俄羅斯方塊的實現(xiàn)

    俄羅斯方塊是一個最初由阿列克謝帕吉特諾夫在蘇聯(lián)設(shè)計和編程的益智類視頻游戲。本文和大家分享了利用Java語言實現(xiàn)這一經(jīng)典的小游戲的示例代碼,需要的可以參考一下
    2022-05-05
  • 基于restTemplate遇到的編碼問題及解決

    基于restTemplate遇到的編碼問題及解決

    這篇文章主要介紹了restTemplate遇到的編碼問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • springboot實現(xiàn)rabbitmq的隊列初始化和綁定

    springboot實現(xiàn)rabbitmq的隊列初始化和綁定

    這篇文章主要介紹了springboot實現(xiàn)rabbitmq的隊列初始化和綁定,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10
  • mybatis Reflector反射類的具體使用

    mybatis Reflector反射類的具體使用

    Reflector類是MyBatis反射模塊的核心,負責(zé)處理類的元數(shù)據(jù),以實現(xiàn)屬性與數(shù)據(jù)庫字段之間靈活映射的功能,本文主要介紹了mybatis Reflector反射類的具體使用,感興趣的可以了解一下
    2024-02-02
  • logback的AsyncAppender高效日志處理方式源碼解析

    logback的AsyncAppender高效日志處理方式源碼解析

    這篇文章主要為大家介紹了logback的AsyncAppender高效日志處理方式源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • mybatis實現(xiàn)表與對象的關(guān)聯(lián)關(guān)系_動力節(jié)點Java學(xué)院整理

    mybatis實現(xiàn)表與對象的關(guān)聯(lián)關(guān)系_動力節(jié)點Java學(xué)院整理

    這篇文章主要介紹了mybatis實現(xiàn)表與對象的關(guān)聯(lián)關(guān)系_動力節(jié)點Java學(xué)院整理,需要的朋友可以參考下
    2017-09-09
  • SpringBoot使用SpringDoc+OpenAPI3.0實現(xiàn)接口文檔自動生成

    SpringBoot使用SpringDoc+OpenAPI3.0實現(xiàn)接口文檔自動生成

    本文介紹了在前后端分離項目中使用SpringDoc實現(xiàn)接口文檔自動生成的方法,包括核心依賴、啟動配置、常用注解、生產(chǎn)環(huán)境配置、帶Token權(quán)限接口調(diào)試等內(nèi)容,提高了接口文檔的生成效率和維護性,需要的朋友可以參考下
    2026-03-03

最新評論

克拉玛依市| 宜宾县| 郯城县| 施秉县| 深泽县| 怀来县| 湟源县| 冀州市| 蚌埠市| 赤峰市| 温宿县| 吴川市| 潼南县| 文登市| 牙克石市| 平顺县| 宁城县| 察雅县| 新干县| 鄂托克前旗| 怀安县| 宜城市| 太谷县| 永顺县| 峡江县| 宜川县| 嘉荫县| 綦江县| 景谷| 个旧市| 泗阳县| 南岸区| 永清县| 庐江县| 罗平县| 山阴县| 金门县| 绥宁县| 威宁| 鹤壁市| 班玛县|