Spring MVC 启动过程(未续待完)

Spring 启动包括几个步骤

我们看下配置文件

<serlvet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.srpingframework.web.servlet.DispatcherServlet</servlet-class>
    <load-startup>2</load-startup>
</serlvet>

<serlvet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfiguration</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.springframwork.web.context.ContextLoaderListener
    </listener-class>
</listener>

从配置文件,我们可以看到一个监听器和 DispatcherSerlvet。监听器负责在 Web 容器中建立起双亲 IOC 容器,另一个生成相应的 WebApplicationContext 并将其初始化。

然后 DispatcherServlet 的父类 FramworkServlet 中进行获取刚刚 ContextLoderListener 已经加载好的 IOC 容器。然后交给了 DispacherServlet 进行 getBean()

Spring MVC 请求的过程是什么?

首先我们知道了在 web.xml 上,我们用 DispatcherServlet 拦截了所有请求。而其实 DispatcherServlet 也是一个 Servlet。这里有一个这样的继承图:

graph LR
DispatcherServlet-->FrameworkServlet
FrameworkServlet-->HttpServletBean
HttpServletBean-->HttpServlet
HttpServlet-->GenericServlet

Spring MVC 整个框架初始化在哪里?

DispatcherServletinitStrategies 方法中。

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);
}

这里有初始化媒体的上传组件、国际化 localResovler、支持 request 的映射 requestMapping 等等。在这里加载是因为方便 DispatcherServlet 进行操作。

DispatcherServlet 真正开始分发的位置在哪里?

前面说了,其实 DispatcherServlet 是一个 servlet,所以它的 doService 方法是拦截所有请求的地方。

    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 进行一些前置处理
        ...

        try {
            // 开始分发
            this.doDispatch(request, response);
        } finally {
                // 进行一些后置处理    
                ...
            }
        }
    }

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            try {
                ModelAndView mv = null;
                Object dispatchException = null;

                try {
                    // 检查是不是图片或其他文件上传的请求
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                    // 获取相应的 HandlerExecutionChain(其实这个 HandlerExecutionChain 封装了请求的 controller 和 相应的拦截器)
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null || mappedHandler.getHandler() == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

                    // 交付给相应的 Adapter
                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if (this.logger.isDebugEnabled()) {
                            this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                        }

                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }

                    // 调用相关的请求之前的拦截器
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }

                    // 使用 Adapter 开始处理请求并返回视图。记住,Adapter 才是真正进行处理的流程。
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                    // 生成以请求的路径为视图名
                    this.applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }

                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
            } catch (Exception var22) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
            } catch (Throwable var23) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }

猜你喜欢

转载自blog.csdn.net/T1014216852/article/details/80475765