spring4.3.6源代码 - webmvc - DispatcherServlet 初始化、接收请求

37 篇文章 0 订阅
21 篇文章 0 订阅

 

初始化(init)

// Set bean properties from init parameters.
try {
    PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);

    /*
        用BeanWrapperImpl对象包装DispatcherServlet
     */
    BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); // org.springframework.beans.BeanWrapperImpl
    ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
    bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment())); // customEditors[Resource.class]
    initBeanWrapper(bw); // 空方法

    /*
        把web.xml中的配置设置到 org.springframework.web.servlet.DispatcherServlet
     */
    bw.setPropertyValues(pvs, true);
} catch (BeansException ex) {
    logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
    throw ex;
}

/*
    1、获取在ContextLoaderListener初始化的 XmlWebApplicationContext
    2、创建《子上下文》
        ConfigurableWebApplicationContext wac = new XmlWebApplicationContext(); // 实例化
        wac.setEnvironment(getEnvironment());
        wac.setParent(parent); // 设置对父类的依赖
        wac.setConfigLocation(getContextConfigLocation());
        configureAndRefreshWebApplicationContext(wac); // !!!!
        {
            1、给上下文设置id
                wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(getServletContext().getContextPath()) + '/' + getServletName());
            2、设置servlet的属性
                wac.setServletContext(getServletContext());
                wac.setServletConfig(getServletConfig());
                wac.setNamespace(getNamespace());
            3、设置监听器
                wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));
            4、设置属性源
                ConfigurableEnvironment env = wac.getEnvironment();
                if (env instanceof ConfigurableWebEnvironment) {
                    ((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
                }
            5、应用初始化器、刷新《子上下文》
                postProcessWebApplicationContext(wac); // 空方法
                applyInitializers(wac); // 应用初始化器  !!!!
                wac.refresh();
                {
                    // 。。。同 XmlWebApplicationContext 。。。
                    // 解析applicationContext.xml文件 。。。
                    // 扫描bean,调用PostProcessors 。。。
                    // 启动《实现SmartLifecycle接口且配置自动启动的》的bean 。。。
                    // 等等。。。
                    // 。。。。
                }
        }

     3、刷新《子上下文》
        // 识别applicationContext.xml文件中配置的一些bean,如果没有配置,就是使用默认的
        initMultipartResolver(context);
            // this == DispatcherServlet
            this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
        initLocaleResolver(context);
            // this == DispatcherServlet
            this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
        initThemeResolver(context);
            this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
        initHandlerMappings(context); // 获取处理器映射
            1、获取applicationContext.xml实现 HandlerMapping 接口的bean列表
            2、如果1没获取到,走默认策略
                org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ 根据xml文件中配置的beanName来匹配
                org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping !!!已经过期 -- 根据类上的@RequestMapping注解来匹配
        initHandlerAdapters(context);
            1、获取applicationContext.xml实现 HandlerAdapter 接口的bean列表
            2、如果1没获取到,走默认策略
                org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
                org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
                org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
        initHandlerExceptionResolvers(context);
            1、获取applicationContext.xml实现 HandlerExceptionResolver 接口的bean列表
            2、如果1没获取到,走默认策略
                org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
                org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
                org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
        initRequestToViewNameTranslator(context);
            1、获取applicationContext.xml实现 RequestToViewNameTranslator 接口的bean
                this.viewNameTranslator = context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
            2、如果1没获取到,走默认策略
                org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
        initViewResolvers(context);
            1、获取applicationContext.xml实现 ViewResolver 接口的bean列表
            2、如果1没获取到,走默认策略
                org.springframework.web.servlet.view.InternalResourceViewResolver
        initFlashMapManager(context);
            1、获取applicationContext.xml实现 FlashMapManager 接口的bean列
                this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
            2、如果1没获取到,走默认策略
                org.springframework.web.servlet.support.SessionFlashMapManager
 */
// Let subclasses do whatever initialization they like.
initServletBean(); // !!!!

接收请求(processRequest)

/*
    用 SimpleLocaleContext 包装 request.getLocale()
 */
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = buildLocaleContext(request); // 本地

/*
    用 ServletRequestAttributes 包装 request、response对象
 */
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes); // 本地化

/*
    创建 WebAsyncManager 对象,并设置到 request
 */
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); // 异步

/*
    设置 asyncManager 的拦截器
 */
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

/*
    设置 localeContext、requestAttributes 到当前上下文
 */
initContextHolders(request, localeContext, requestAttributes); // 多少线程“参数本地化”

try {
    /*
        Map<String, Object> attributesSnapshot = null;
        if (WebUtils.isIncludeRequest(request)) { // “include”请求
            attributesSnapshot = new HashMap<String, Object>();
            Enumeration<?> attrNames = request.getAttributeNames();
            while (attrNames.hasMoreElements()) {
                String attrName = (String) attrNames.nextElement();
                if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
                    attributesSnapshot.put(attrName, request.getAttribute(attrName)); // 属性快照
                }
            }
        }

        // Make framework objects available to handlers and view objects.
        request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext()); // !!!!  getWebApplicationContext() === org.springframework.web.context.support.XmlWebApplicationContext
        request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver); // org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
        request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver); // org.springframework.web.servlet.theme.FixedThemeResolver
        request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource()); // !!!!  getThemeSource() === org.springframework.web.context.support.XmlWebApplicationContext

        FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response); // org.springframework.web.servlet.support.SessionFlashMapManager
        if (inputFlashMap != null) {
            request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
        }
        request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
        request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

        doDispatch(request, response); // !!!
        {
            try {
                try {
                    1、处理请类型
                        processedRequest = checkMultipart(request); // 检查是否Multipart类型(如:文件上传),如果是,就进行解析

                    2、获取当前请求的 mappedHandler(HandlerExecutionChain)
                        mappedHandler = getHandler(processedRequest); // 决策一个适合processedRequest的Handler,执行链管理器HandlerExecutionChain
                        {
                            // handlerMappings = [
                            //     org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping  根据xml文件中配置的beanName来匹配
                            //     org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping  !!!已经过期 -- 根据类上的@RequestMapping注解来匹配
                            //     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping  !!!新的
                            // ]
                            for (HandlerMapping hm : this.handlerMappings) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace(
                                            "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
                                }
                                HandlerExecutionChain handler = hm.getHandler(request);
                                if (handler != null) {
                                    return handler;
                                }
                            }
                            return null;
                        }
                    3、获取当前请求 mappedHandler 的适配器 ha(HandlerAdapter)
                        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 决策一个适合Handler的“Handler适配器”, 四种类型的适配器
                        {
                            // handlerAdapters = [
                            //      org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
                            //      org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
                            //      !!! 从3.2为止这个过期 org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
                            //      org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
                            // ]
                            for (HandlerAdapter ha : this.handlerAdapters) {
                                if (ha.supports(handler)) {
                                    return ha;
                                }
                            }
                        }
                    4、应用《前置处理器》 --- 调用拦截器列表的 preHandle 方法
                        if (!mappedHandler.applyPreHandle(processedRequest, response)) { // 调用 HandlerExecutionChain 的applyPreHandle方法,迭代调用Handler的拦截器的preHandle方法
                            return;
                        }

                    5、执行 HandlerAdapter
                        mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 执行handler的方法,返回值 org.springframework.web.servlet.ModelAndView

                    6、应用《默认视图名称》
                        applyDefaultViewName(processedRequest, mv); // 如果没有设置“视图”信息,会自动应用“视图”

                    7、应用《后置处理器》 --- 调用拦截器列表的 postHandle 方法
                        mappedHandler.applyPostHandle(processedRequest, response, mv);  // 调用 HandlerExecutionChain 的applyPostHandle方法 ,迭代调用Handler的拦截器的postHandle方法

                } catch (Exception ex) {
                    dispatchException = ex;
                }

                8、处理返回结果
                    1、构建 ModelAndView 对象
                        没有异常,
                            不进行处理

                        存在异常
                            用《异常解析器》,构建异常视图 ModelAndView
                                for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) { // 迭代异常解析器列表
                                    exMv = handlerExceptionResolver.resolveException(request, response, handler, ex); // 解析异常
                                    if (exMv != null) {
                                        break;
                                    }
                                }
                    2、执行渲染
                        1、获取Local
                            Locale locale = this.localeResolver.resolveLocale(request); // 检查语言
                            response.setLocale(locale);
                        2、渲染
                            view.render(mv.getModelInternal(), request, response); // 渲染

                    3、应用《完成处理器》 --- 调用拦截器列表的 afterCompletion 方法
                        mappedHandler.triggerAfterCompletion(request, response, null);

             } catch (Exception ex) {
                9、应用《完成处理器》 --- 调用拦截器列表的 afterCompletion 方法
                mappedHandler.triggerAfterCompletion(request, response, ex);
            }
        }
     */
    doService(request, response); // !!!! 子类
}
catch (ServletException ex) {
    failureCause = ex;
    throw ex;
}
catch (IOException ex) {
    failureCause = ex;
    throw ex;
}
catch (Throwable ex) {
    failureCause = ex;
    throw new NestedServletException("Request processing failed", ex);
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值