栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringMVC

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringMVC

1.MVC是什么?

M是Model,V是View,C是Controller。

View很好理解,就是用户面对的视图。

Model可以理解成业务层和持久层。

Controller接收用户输入的请求数据,调用Model,返回View。

2.SpringMVC处理请求的流程

要点:

1 DispatcherServlet:称为中央调度器。在Tomcat服务器启动时,会解析web.xml文件,实例化DispatcherServlet对象。在DispatcherServlet对象的的init()方法中,根据指定的bean.xml文件,创建spring容器,创建controller,service,dao等bean对象。

2 关于子父容器的概念:DispatcherServlet对象创建时会在对象内部创建一个spring容器。如果我们有多个DispatcherServlet对象呢?理所当然会有多个spring容器,每个spring容器归属于独立的DispatcherServlet对象。但如果这样的话,多个spring容器内会存在冗余的对象。这样是对资源的浪费,能否有一种解决办法能解决冗余。答案肯定是有的,就是创建一个父容器,子容器共享父容器内的对象。利用ContextLoaderListener实现。ContextLoaderListener监听器在Tomcat启动时读取contextConfigLocation对应的路径创建一个父容器。之后我们创建的DispatcherServlet内的容器会通过setParent()方法自动设置父子关系,框架内部实现。事实上多个DispatcherServlet其实也没什么用处,一个其实够用了。如果只有一个DispatcherServlet那么也没有必要有父子容器。

3 DispatcherServlet如何工作的?DispatcherServlet在创建时需要指定他将要识别的uri,可以用通配符*。如"*StringHttpMessageConverterStringtext/plain, */*MappingJackson2HttpMessageConverterObjectapplication/json, application/*+jsonAllEncompassingFormHttpMessageConverterMap>application/x-www-form-urlencoded, multipart/form-dataSourceHttpMessageConverterSourceapplication/xml, text/xml, application/*+xml

6.控制器的异常处理

1.模块内局部异常处理。在处理器类中定义某方法,使用@ExceptionHandler注解(value=异常类.class)表示,当处理器类中的任意处理器抛出对应异常就会执行异常处理方法。

2.全局异常处理。定义一个异常处理类,用@ControllerAdvice标识,类中所有方法都用@ExceptionHandler注解标识。

7.拦截器interceptor

1.如何定义拦截器?

1.1实现HandlerInterceptor接口。接口中定义了三个方法,preHandler,postHandler,afterCompletion。

preHandler表示在handler执行前执行,通常用来做一些预处理,如认证,安全等,preHandler返回值是Boolean类型的,只有返回true时才会执行handler方法,返回false当前请求就被截断了。

postHandler表示在handler执行之后执行,可以对handler处理的ModelAndView做二次处理。

afterCompletion只有在preHandler方法返回true才会执行。

1.2声明拦截器,配置拦截路径

2.多个拦截器的执行顺序?

按照拦截器定义的顺序 preHandler1->preHandler2...->handler...->postHandler2->postHandler1...->afterCompletion2->afterCompletion1。

preHandler返回false之后后面的操作直接中断。

afterCompletion根据preHandler的返回结果来判断是否执行的,返回true就执行,false就不执行。

8.java配置springmvc

定义一个类实现WebMvcConfigurer接口用@Configuration标识,重写里面的方法即可。

9.DispatcherServlet底层是一个Servlet,继承了frameworkServlet。

frameworkServlet继承HttpServletBean。 HttpServletBean继承HttpServlet。HttpServlet继承GenericServlet。GenericServlet继承Servlet。

9.DispatcherServlet初始化的过程 

1.DispatcherServlet是一个Servlet,符合Servlet生命周期。创建DispatcherServlet时首先调用init方法初始化。HttpServletBean对init方法进行了重写,DispatcherServlet执行的init其实是继承而来的。在HttpServletBean的init中继续调用frameworkServlet的initServletBean方法。在initServletBean中调用initWebApplication方法初始化容器。在initWebApplication中调用createWebApplicationContext通过反射创建容器,然后onFresh刷新容器,调用initStrategies进行组件的初始化,最后将容器放入全局作用域。

 

 

 

 

 

 

因为DIspatcherServlet继承了上面全部方法,所以在DispatcherServlet初始化时会执行一遍这些方法

10.DispatcherServlet调用服务的过程

Servlet处理服务的方法是service方法。当然DispatcherServlet也不例外。调用service方法处理请求,然后调用doService方法,最终调用doDispatch方法处理请求。

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;

                //调用HandlerMapping找到对应的handler对象封装成执行链对象并返回
                    mappedHandler = this.getHandler(processedRequest);

                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

                //获取可执行该handler的HandlerAdapter实现类对象
                    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 ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }

                 //执行拦截器的preHandler方法
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
                    
                 //真正执行handler方法。这一步其实做了非常多工作。
                 //HandlerAdaptr帮我们从请求中获取参数,String转成参数类型。
                 //将java对象放入响应体等等操作。
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                    this.applyDefaultViewName(processedRequest, mv);

                  //执行postHandler方法
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }
 //最后是对视图的处理和判断mv中是否有异常,有就进行异常处理和afterCompletion方法的执行。
                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);
            }

        }
    }

11.springmvc处理服务的最终流程

1.用户请求到达,DispatcherServlet进行捕获

2.根据uri发给HandlerMapping处理,没找到就报404。

3.找到了的话HandlerMapping就把handler和拦截器集合和索引封装起来给DispatcherServlet返回一个HandlerExceuctionChain。

4.DispatcherServlet调用HandlerAdapter找到合适的,能处理这个handler的HandlerAdapter实现类。

5.得到这个HandlerAdapter实现类之后,开始执行拦截器preHandler方法。(正向)

6.handlerAdapter提取request中的请求参数并将string转换成java对象或类型,赋值到handler方法的形参上,接着执行真正handler方法。HTTPMessageConverter实现类对返回值进行消息转换。

7.返回一个ModelAndView对象给DispatcherServlet。

8.执行postHandler方法(反向)

9.渲染视图。判断ModelAndView中是否有异常,处理异常。执行afterCompletion方法(反向)。

10返回视图,返回数据。

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/786504.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号