springmvc DispatchServlet初始化九大載入策略(一)

來源:互聯網
上載者:User

標籤:ant   accept   hand   tst   set   ext   容器   could not   commons   

SpringMVC 容器初始化時,

protected void onRefresh(ApplicationContext context) {    this.initStrategies(context);}protected void initStrategies(ApplicationContext context) {    this.initMultipartResolver(context);    this.initLocaleResolver(context);    this.initThemeResolver(context);    this.initHandlerMappings(context);    this.initHandlerAdapters(context);    this.initHandlerExceptionResolvers(context);    this.initRequestToViewNameTranslator(context);    this.initViewResolvers(context);    this.initFlashMapManager(context);}

 

1. initMultipartResolver 檔案上傳

源碼:

this.multipartResolver = (MultipartResolver)context.getBean("multipartResolver", MultipartResolver.class);

MultipartResolver介面定義如下:

public interface MultipartResolver {    // 檢查要求標頭是否包含檔案流上傳    boolean isMultipart(HttpServletRequest var1);        // 檔案流上傳請求解析方法,解析後封裝在 MultipartHttpServletRequest 對象中    MultipartHttpServletRequest resolveMultipart(HttpServletRequest var1) throws MultipartException;      //    void cleanupMultipart(MultipartHttpServletRequest var1);}

我們知道,相應的請求會被DispatchServlet的doDispatch方法攔截,doDispatch方法中共首先就會調用checkMultipart方法檢查請求是否是包含檔案流:

protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {        if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {            if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {                this.logger.debug("...");            } else if (this.hasMultipartException(request)) {                this.logger.debug("...");            } else {                try {                    // 具體的檔案流解析方法                    return this.multipartResolver.resolveMultipart(request);                    ...
}  
配置例子

CommonsFileUploadSupport實現了 MultipartResolver 介面

//上傳檔案配置@Bean(name = "multipartResolver")public CommonsFileUploadSupport commonsFileUploadSupport(){    CommonsFileUploadSupport resolver = new CommonsMultipartResolver();    resolver.setMaxInMemorySize(40960);    resolver.setMaxUploadSize(10485760000L);    return resolver;}

  

2. initLocaleResolver 國際化

DispatcherServlet.properties檔案:

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolverorg.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolverorg.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMappingorg.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterorg.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverorg.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslatororg.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolverorg.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

DispatchServlet中定義一個靜態容器初始化預設defaultStrategies方法塊,如果使用者沒有自訂的話,就使用預設的,

static {    // Load default strategy implementations from properties file.    // This is currently strictly internal and not meant to be customized    // by application developers.    try {        ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);        defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);    }    catch (IOException ex) {        throw new IllegalStateException("Could not load ‘" +     DEFAULT_STRATEGIES_PATH + "‘: " + ex.getMessage());    }}

流程:

1. this.localeResolver = getDefaultStrategy(context, LocaleResolver.class); 2. List<T> strategies = getDefaultStrategies(context, strategyInterface)3. String key = strategyInterface.getName();   String value = defaultStrategies.getProperty(key);   // 如果value不為空白, 將value轉換為class類名稱,然後在容器了建立對象   Object strategy = this.createDefaultStrategy(context, clazz);

pringMVC國際化提供了四個國際化的實現的類AcceptHeaderLocaleResolver(預設),FixedLocaleResolver、CookieLocaleResolver和SessionLocaleResolver。

 3. initThemeResolver 主題

主題的實現原理:大概就是把網站版面的css樣式表和圖片之類的檔案和網站的程式進行解耦,程式讀取theme的持久化配置,然後找到相應的css樣式表和圖片,配置網站版面。

要在程式中使用主題,必須設定一個org.springframework.ui.context.ThemeSource的實作類別。SpringMVC IOC容器本身實現了ThemeSource,這個類只是簡單的把責任代理給了一個特定的實作類別,預設情況下這個代理類是:org.springframework.ui.context.support.ResourceBundleThemeSource,這個實作類別可以從classpath目錄下載入一個properties檔案。如設定setBasenamePrefix、setDefaultEncoding等。

原理(實踐)

如:SpringMVC中一套主題對應一個cool.properties檔案,該檔案在classpath根目錄下, 這個檔案列出了主題組成的資源:

styleSheet=/themes/cool/style.cssbackground=/themes/cool/img/coolBg.jpg

properties檔案中的key是指視圖檔案中元素的名稱,value值主題存放的位置。jsp中可以通過jsp檔案可以通過spring:theme來訪問這個key,然後找到value(對應的主題)。

ResourceBundleThemeSourceuses(預設的ThemeSource)的作用是根據主題名找到具體的主題,這個例子中就是找到設定檔themedemo.properties中的,預設情況下ResourceBundleThemeSource使用空的首碼名稱,所以,classpath根目錄下的properties檔案會被載入。如果想制定位置,則可以使用basenamePrefix。

找到主題檔案後,如何去解析?此時就出現了ThemeResolver。

SpringMVC中有實現主題類有3個:

  1. FixedThemeResolver(預設):固定格式的theme,不能在系統運行時動態更改theme。

  2. SessionThemeResolver:可在運行中通過更改cookie中的相應的key值來動態調整theme的值。

  3. CookieThemeResolver:可在運行中通過更改session中的相應的key值來動態調整theme的值

主題載入策略和initLocaleResolver類似,也是如果使用者沒有自訂就採用預設的方式。預設的方式為FixedThemeResolver。

一個例子:

application context .xml設定檔:

<bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource">      <property name="basenamePrefix" value="themes/"></property>  </bean>  <bean id="themeResolver"  class="org.springframework.web.servlet.theme.SessionThemeResolver">      <property name="defaultThemeName" value="red" />  </bean>

簡單敘述為:ThemeResolver找到themes/目錄下的所有properties中,然後SessionThemeResolver在發生改變主題請求後來解析主題。

附:如果需要根據使用者請求來改變主題,則需要使用ThemeChangeInterceptor攔截器來改變主題。(攔截器有關的知識可以看本文下面的handlerMapping)

參考:

https://www.xuebuyuan.com/zh-tw/1578077.html

52915063

 

springmvc DispatchServlet初始化九大載入策略(一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.