美文网首页
Spring mvc-容器初始化分析

Spring mvc-容器初始化分析

作者: 行动的侏儒 | 来源:发表于2018-04-19 23:41 被阅读0次

    1.Spring mvc:
    基于spring的处理web请求的半封装框架(基于servlet处理web层体系的延升框架)
    Spring mvc 本质上是一个servlet服务


    spring mvc原理

    Spring mvc重写了HttpServlet的init()和service(),先看看DispatcherServlet的继承关系


    Servlet类的继承关系

    DispatcherServlet初始化过程:
    1.重写init()
    HttpServletBean重写init()方法

    public final void init() throws ServletException {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Initializing servlet '" + this.getServletName() + "'");
            }
            //将servlet的配置注入
            PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
            if (!pvs.isEmpty()) {
                try {
                    BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
                    ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
                    bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
                    this.initBeanWrapper(bw);
                    bw.setPropertyValues(pvs, true);
                } catch (BeansException var4) {
                    if (this.logger.isErrorEnabled()) {
                        this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
                    }
    
                    throw var4;
                }
            }
            //初始化servlet
            this.initServletBean();
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Servlet '" + this.getServletName() + "' configured successfully");
            }
    
        }
    

    FrameworkServlet重写initServletBean方法

    protected final void initServletBean() throws ServletException {
            this.getServletContext().log("Initializing Spring FrameworkServlet '" + this.getServletName() + "'");
            if (this.logger.isInfoEnabled()) {
                this.logger.info("FrameworkServlet '" + this.getServletName() + "': initialization started");
            }
    
            long startTime = System.currentTimeMillis();
    
            try {
                //初始化上下文
                this.webApplicationContext = this.initWebApplicationContext();
                this.initFrameworkServlet();
            } catch (RuntimeException | ServletException var5) {
                this.logger.error("Context initialization failed", var5);
                throw var5;
            }
    
            if (this.logger.isInfoEnabled()) {
                long elapsedTime = System.currentTimeMillis() - startTime;
                this.logger.info("FrameworkServlet '" + this.getServletName() + "': initialization completed in " + elapsedTime + " ms");
            }
    
        }
    

    initWebApplicationContext初始化上下文对象

    protected WebApplicationContext initWebApplicationContext() {
            WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
            WebApplicationContext wac = null;
            if (this.webApplicationContext != null) {
                wac = this.webApplicationContext;
                if (wac instanceof ConfigurableWebApplicationContext) {
                    ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac;
                    if (!cwac.isActive()) {
                        if (cwac.getParent() == null) {
                            cwac.setParent(rootContext);
                        }
    
                        this.configureAndRefreshWebApplicationContext(cwac);
                    }
                }
            }
    
            if (wac == null) {
                wac = this.findWebApplicationContext();
            }
    
            if (wac == null) {
                wac = this.createWebApplicationContext(rootContext);
            }
    
            if (!this.refreshEventReceived) {
                //onRefresh由DispatcherServlet重写
                this.onRefresh(wac);
            }
    
            if (this.publishContext) {
                String attrName = this.getServletContextAttributeName();
                this.getServletContext().setAttribute(attrName, wac);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Published WebApplicationContext of servlet '" + this.getServletName() + "' as ServletContext attribute with name [" + attrName + "]");
                }
            }
    
            return wac;
        }
    

    DispatcherServlet重写onRefresh()

    protected void onRefresh(ApplicationContext context) {
            this.initStrategies(context);
        }
    
        protected void initStrategies(ApplicationContext context) {
            //进行web层bean的配置
            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);
        }
    

    init完成后,重写service()最后关键点在DispatcherServlet的doDispatcher()方法

    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;
                        //获取method映射器,请求到处理器的映射,映射成功后返回HandlerExecutionChain对象
                        mappedHandler = this.getHandler(processedRequest);
                        if (mappedHandler == null) {
                            this.noHandlerFound(processedRequest, response);
                            return;
                        }
    
                        //适配器,可以支持多种类型的处理器
                        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;
                        }
    
                        //处理业务
                        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);
                }
    
            }
        }
    

    相关文章

      网友评论

          本文标题:Spring mvc-容器初始化分析

          本文链接:https://www.haomeiwen.com/subject/sargkftx.html