zoukankan      html  css  js  c++  java
  • SpringMVC源码阅读-dispatcher组件初始化过程(三)

    说明

    前面我们看到了是dispatcher负责组件的初始化

    调用链:

    org.springframework.web.servlet.HttpServletBean#init

    ->

    org.springframework.web.servlet.FrameworkServlet#initServletBean

    ->

    org.springframework.web.servlet.FrameworkServlet#initWebApplicationContext

    ->

    org.springframework.web.servlet.DispatcherServlet#onRefresh

    protected void onRefresh(ApplicationContext context) {
            this.initStrategies(context);
        }
        /**
         * 初始化spring mvc组件
         * @param context
         */
        protected void initStrategies(ApplicationContext context) {
            //<1>初始化上传文件Resolver
            this.initMultipartResolver(context);
            //<2>初始化国际化Resolver 不同区域显示不同视图
            this.initLocaleResolver(context);
            //<3>初始化控制页面主题的Resolver
            this.initThemeResolver(context);
            //<4>初始化url映射 mapping
            this.initHandlerMappings(context);
            //<5>初始化Handler适配器
            this.initHandlerAdapters(context);
            //<6>初始化全局异常处理HandlerExceptionResolver
            this.initHandlerExceptionResolvers(context);
    //<7>
    this.initRequestToViewNameTranslator(context);
    //<8>
    this.initViewResolvers(context);
    //<9>
    this.initFlashMapManager(context); }

    <1>initMultipartResolver

    这个组件主要用于解析Content-Type为 multipart/*

     private void initMultipartResolver(ApplicationContext context) {
            try {
                //<1>从当前容器里面获取MultipartResolver实现类
                this.multipartResolver = (MultipartResolver)context.getBean("multipartResolver", MultipartResolver.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Using MultipartResolver [" + this.multipartResolver + "]");
                }
            } catch (NoSuchBeanDefinitionException var3) {
                this.multipartResolver = null;
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Unable to locate MultipartResolver with name 'multipartResolver': no multipart request handling provided");
                }
            }
    
        }

    主要处理请求头类型( Content-Type )为 multipart/* 的请求

    <1>

       <!-- mulitipart -->
        <bean id="multipartResolver"
              class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="defaultEncoding" value="UTF-8"/>
            <property name="maxUploadSize" value="5242880"/>
        </bean>

    <2>initLocaleResolver

    private void initLocaleResolver(ApplicationContext context) {
            try {
                this.localeResolver = (LocaleResolver)context.getBean("localeResolver", LocaleResolver.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
                }
            } catch (NoSuchBeanDefinitionException var3) {
                this.localeResolver = (LocaleResolver)this.getDefaultStrategy(context, LocaleResolver.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Unable to locate LocaleResolver with name 'localeResolver': using default [" + this.localeResolver + "]");
                }
            }
    
        }

    初始化国际化组件 使用例子:https://www.cnblogs.com/liukemng/p/3750117.html

    <3>initThemeResolver

      private void initThemeResolver(ApplicationContext context) {
            try {
                this.themeResolver = (ThemeResolver)context.getBean("themeResolver", ThemeResolver.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Using ThemeResolver [" + this.themeResolver + "]");
                }
            } catch (NoSuchBeanDefinitionException var3) {
                this.themeResolver = (ThemeResolver)this.getDefaultStrategy(context, ThemeResolver.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Unable to locate ThemeResolver with name 'themeResolver': using default [" + this.themeResolver + "]");
                }
            }
    
        }

    <4>initHandlerMappings

    private void initHandlerMappings(ApplicationContext context) {
            this.handlerMappings = null;
            //默认为true可以通过inin-parameter修改 前面容器初始化过程 BeanWapper
            if (this.detectAllHandlerMappings) {
                /**
                 * 从容器获取HandlerMapping的实现类
                 * 这里会获取到
                 * org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
                 * org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
                 */
                Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
                if (!matchingBeans.isEmpty()) {
                    this.handlerMappings = new ArrayList(matchingBeans.values());
                    //这里会获取Mapping的的Order注解的value进行排序
                    AnnotationAwareOrderComparator.sort(this.handlerMappings);
                }
            } else {
                try {
                    //直接获取容器名称为handlerMapping
                    HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
                    this.handlerMappings = Collections.singletonList(hm);
                } catch (NoSuchBeanDefinitionException var3) {
                    ;
                }
            }
    
            //这里应该是获取默认的HandlerMapping
            if (this.handlerMappings == null) {
    
                this.handlerMappings = this.getDefaultStrategies(context, HandlerMapping.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("No HandlerMappings found in servlet '" + this.getServletName() + "': using default");
                }
            }
    
        }

    使用例子:https://blog.csdn.net/neweastsun/article/details/79213867

    <5>initHandlerAdapters

    适配器模式 因为conroller不止是@Controller还有可能是servlte 再或者我们自定义注解@MyController

      private void initHandlerAdapters(ApplicationContext context) {
            this.handlerAdapters = null;
            /**
             * 默认为true 可以通过init-parameter修改
             */
            if (this.detectAllHandlerAdapters) {
                /**
                 * 从容器获取HandlerAdapter 我这里获取到的是
                 * org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
                 * org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
                 * org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
                 */
                Map<String, HandlerAdapter> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
                if (!matchingBeans.isEmpty()) {
                    this.handlerAdapters = new ArrayList(matchingBeans.values());
                    //读取sort注解标签进行排序
                    AnnotationAwareOrderComparator.sort(this.handlerAdapters);
                }
            } else {
                try {
                    //从容器获取id为handlerAdapter的
                    HandlerAdapter ha = (HandlerAdapter)context.getBean("handlerAdapter", HandlerAdapter.class);
                    this.handlerAdapters = Collections.singletonList(ha);
                } catch (NoSuchBeanDefinitionException var3) {
                    ;
                }
            }
            //加载默认额
            if (this.handlerAdapters == null) {
                this.handlerAdapters = this.getDefaultStrategies(context, HandlerAdapter.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("No HandlerAdapters found in servlet '" + this.getServletName() + "': using default");
                }
            }
    
        }

    <6>initHandlerExceptionResolvers

    用于全局捕获异常处理器

     private void initHandlerExceptionResolvers(ApplicationContext context) {
            this.handlerExceptionResolvers = null;
            if (this.detectAllHandlerExceptionResolvers) {
                Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
                if (!matchingBeans.isEmpty()) {
                    this.handlerExceptionResolvers = new ArrayList(matchingBeans.values());
                    AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
                }
            } else {
                try {
                    HandlerExceptionResolver her = (HandlerExceptionResolver)context.getBean("handlerExceptionResolver", HandlerExceptionResolver.class);
                    this.handlerExceptionResolvers = Collections.singletonList(her);
                } catch (NoSuchBeanDefinitionException var3) {
                    ;
                }
            }
    
            if (this.handlerExceptionResolvers == null) {
                this.handlerExceptionResolvers = this.getDefaultStrategies(context, HandlerExceptionResolver.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("No HandlerExceptionResolvers found in servlet '" + this.getServletName() + "': using default");
                }
            }
    
        }

    <7>initRequestToViewNameTranslator

    ViewResolver是根据ViewName查找VIew,但有的Handler处理完后并没有设置View也没有ViewName,这时需要从request获取viewName,RequestToViewNameTranslator就是做这个事情。

     private void initRequestToViewNameTranslator(ApplicationContext context) {
            try {
                this.viewNameTranslator = (RequestToViewNameTranslator)context.getBean("viewNameTranslator", RequestToViewNameTranslator.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Using RequestToViewNameTranslator [" + this.viewNameTranslator + "]");
                }
            } catch (NoSuchBeanDefinitionException var3) {
                this.viewNameTranslator = (RequestToViewNameTranslator)this.getDefaultStrategy(context, RequestToViewNameTranslator.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator': using default [" + this.viewNameTranslator + "]");
                }
            }
    
        }

    <8>initViewResolvers

    ViewResolver是根据ViewName查找VIew

    private void initViewResolvers(ApplicationContext context) {
            this.viewResolvers = null;
            if (this.detectAllViewResolvers) {
                Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
                if (!matchingBeans.isEmpty()) {
                    this.viewResolvers = new ArrayList(matchingBeans.values());
                    AnnotationAwareOrderComparator.sort(this.viewResolvers);
                }
            } else {
                try {
                    ViewResolver vr = (ViewResolver)context.getBean("viewResolver", ViewResolver.class);
                    this.viewResolvers = Collections.singletonList(vr);
                } catch (NoSuchBeanDefinitionException var3) {
                    ;
                }
            }
    
            if (this.viewResolvers == null) {
                this.viewResolvers = this.getDefaultStrategies(context, ViewResolver.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("No ViewResolvers found in servlet '" + this.getServletName() + "': using default");
                }
            }
    
        }

    <9>initFlashMapManager

    我们都知道,重定向时一般都是不传数据的,如果一定要传数据,只能在URL中拼接字符串来传递,但是通过拼接字符串有缺点,比如长度问题,安全问题  

    通过FlashManager异常发送

     private void initFlashMapManager(ApplicationContext context) {
            try {
                this.flashMapManager = (FlashMapManager)context.getBean("flashMapManager", FlashMapManager.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Using FlashMapManager [" + this.flashMapManager + "]");
                }
            } catch (NoSuchBeanDefinitionException var3) {
                this.flashMapManager = (FlashMapManager)this.getDefaultStrategy(context, FlashMapManager.class);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Unable to locate FlashMapManager with name 'flashMapManager': using default [" + this.flashMapManager + "]");
                }
            }
    
        }
  • 相关阅读:
    Vue自定义指令
    Vue实例生命周期
    Vue学习目录
    Vue表单控件绑定
    Vue事件处理
    Vue数组更新及过滤排序
    Vue模板逻辑
    Vue模板内容
    Vue实例对象的数据选项
    Vue组件基础用法
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12192923.html
Copyright © 2011-2022 走看看