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

        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值