博主之前每次去面试必问的问题:“讲一下spring mvc的执行流程以及常用组件的作用”;
记得第一次和面试官说了大概的流程是这样的:“服务器收到一个请求后会先去HandlerMapping中匹配url,找到url之后用HandlerAdapter 适配器去执行这个控制器(controller层),执行完之后返回一个modelAndView,然后通过视图解析器ViewResolver解析后得到一个view对象,这个view就是渲染好的jsp页面,返回给前端页面”;
(等了一会看着我)面试官:“ 就这样。。。没啦?”;
懵逼的我:“嗯,没了”;
面试官:“那你回家等消息吧!”;
其实吧,博主说的没错,只是说少了,不够详细,如果是面试初级java开发,这样讲是没问题的,妥妥地给过了,但我是谁啊,我可是要成为架构师的人啊! 回答出这种答案,老板怎么放心把项目交给我呢。于是啊,吸取了教训,我就在家潜心研究,经过七七四十九天的研究、九九八十一次的练习,终于让我掌握了这门核心技术;
springMVC是一种web层mvc框架;是spring的一个模块,拥有spring的特性,通过策略接口,Spring框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText 和 POI。Spring MVC 框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术。Spring的MVC框架主要由DispatcherServlet、处理器映射、处理器(控制器)、视图解析器、视图组成。
都知道叫做spring mvc,mvc是什么东东呢?其实就是三层架构, 在过去架构都是两层的,就是浏览器通过servlet后直接访问JSP页面,也就是说所有的java代码都是在jsp页面里面写的,就连访问数据库也是在jsp页面,小型项目这样开发没什么问题,因为快嘛,但是大型项目是需要迭代的,是需要增加功能和模块的,你这么写的话,我后期维护起来很麻烦啊;而且java代码和html标签混搭,这样代码的可读性也不高;所以就衍生出了MVC三层架构,
M : 表示model,翻译成中文叫做模型,对应数据库;
V : 表示View,翻译为中文叫做视图,对应前端的页面,比如jsp
C : 表示 Controller ,翻译是控制层,对应servlet的请求映射;
终于到重点了,其实我在开头的时候已经答对了一半了,只是呢,少了一个叫做拦截器的东东,还有一些其他的细节,看下面这张图就明白了
在mvc里面,最重要的无非就这几样 DispatcherServlet 、 HandlerMapping 、 HandlerExecutionChain 、 HandlerInterceptor拦截器、 HandlerAdapter、 ModelAndView、ViewResolver 、 View;别着急,我们一个个讲解它们的作用是什么;
DispatcherServlet 的中文叫做前端控制器 ,也就叫中央调度器,用户发送的所有请求都会经过这个接口,由Servlet调用,是用来拦截所有请求的url的入口,并根据url地址分发到不同的controller ;在web.xml中配置后即可使用
SpringMVC_01
springmvc
org.springframework.web.servlet.DispatcherServlet
1
springmvc
/
HandlerMapping的作用就是解析请求链接,然后根据请求链接找到执行这个请求的类(HandlerMapping所说的handler,也就是我们写的Controller或是Action),也叫做控制器映射器,如果未匹配到控制器,则返回404错误;
HandlerExecutionChain 是Handler的执行链,我叫他控制器执行链,包含控制器对象handler、拦截器 interceptor。所以HandlerExecutionChain 提供了getHandler、getInterceptors方法,配置文件中配置的interceptor都会加入到HandlerExecutionChain;需要注意的是,拦截器的列表里面除了我们配置的拦截器之外,还有一个springmvc自己维护的拦截器;
控制器的拦截器,一般都是作为扩展使用,一共有三个方法:
代码示例
package com.Spring.Boot.controller.Interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* springmvc拦截器
*
*/
@Component
public class MvcInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("处理器处理请求之前被调用");
// 返回true正常执行,返回false 表示拦截请求,
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// preHandle方法返回false则不会执行到这里
System.out.println("处理器处理请求执行完成后调用");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// preHandle方法返回false则不会执行到这里
System.out.println("DispatcherServlet完全处理完请求后被调用");
}
}
打印结果
HandlerAdapter字面上的意思就是处理适配器,它的作用用一句话概括就是调用具体的方法对用户发来的请求来进行处理。当handlerMapping获取到执行请求的controller时,DispatcherServlte会根据controller对应的controller类型来调用相应的HandlerAdapter来进行处理。
执行过程 : DispatcherServlte会根据handlerMapping传过来的controller与已经注册好了的HandlerAdapter一一匹配,看哪一种HandlerAdapter是支持该controller类型的,如果找到了其中一种HandlerAdapter是支持传过来的controller类型,那么该HandlerAdapter会调用自己的handle方法
从名字上看ModelAndView中的Model代表模型,View代表视图,这里的模型就是在controller层中ModelMap中添加的值;
ModelAndView对象有两个作用:
设置转向地址,如下所示(这也是ModelAndView和ModelMap的主要区别)
ModelAndView mv = new ModelAndView();
mv.setViewName("statisticalform/popStatistics/onloadPopStatisticsList");
用于传递控制方法处理结果数据到结果页面,也就是说我们把需要在结果页面上需要的数据放到ModelAndView对象中即可,
他的作用类似于 request对象的setAttribute方法的作用,用来在一个请求过程中传递处理的数据。
通过以下方法向页面传递参数:
addObject(String key,Object value);
mv.addObject("list", list);
在页面上可以通过el变量方式$key或者bboss的一系列数据展示标签获取并展示ModelAndView中的数据。
视图解析器,ViewResolver
的主要作用是把一个逻辑上的视图 ModelAndView 解析为一个真正的view视图;
视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户端。视图对象可以是常见的JSP,还可以是Excel或PDF等形式不一的媒体。为了实现视图模型和具体实现技术的解耦;