1.什么是SpringMVC?
SpringMVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model、View、Controller分离,将Web层进行职责解耦,把复杂的Web应用分成逻辑清晰的几个部分,简化开发,减少出错,方便组内开发人员之间的配合
2.SpringMVC的执行流程是什么样的?
- 浏览器发送请求至前端控制器DispatcherServlet
- DispatcherServlet先对请求进行一个简单判断(是简单请求还是Multipart请求),然后DispatcherServlet遍历每一个处理器映射器HandlerMapping,将请求交给每一个HandlerMapping进行匹配
- HandlerMapping接收请求后,对请求进行解析,然后根据解析结果,寻找对应的处理器Handler对象及处理器拦截器HandlerInterceptor,最后将其包装成处理器执行链HandlerExecutionChain对象返还给DispatcherServlet
- DispatcherServlet根据HandlerExcutionChain对象中的Handler寻找与之对应的处理器适配器HandlerAdapter对象,同时执行了HandlerExecutionChain中的拦截器前端方法(preHandler())
- 找到对应的HandlerAdapter之后,执行对应的处理器Handler
- Handler执行完毕之后,返还ModelAndView对象给对应的HandlerAdapter,HandlerAdapter再将其返还给DispatcherServlet
- DispatcherServlet接收ModelAndView对象之后,先调用HandlerExcutionChain中的拦截器后端方法(postHandler()),之后遍历所有的视图解析器ViewResolver,匹配ModelAndView对象
- 匹配成功后,ViewResolver将视图名称域响应目标定位对象进行绑定,形成视图View对象返还给DispatcherServlet
- DispatcherServlet根据View对象调用对应的渲染方法,对其进行渲染(合并数据Model、结合View对象中的响应目标定位对象准备响应对象Response、结合合并的数据Model和Response对象形成最终的响应视图)
- DispatcherServelt渲染好View对象之后,执行HandlerExcutionChain的afterCompletion方法,进行最终响应
DispatcherServlet extends FrameworkServlet extends HttpServletBean extends HttpServlet
enum HttpMethod{
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
}
class FrameworkServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse res){
HttpMethod httpMethod=HttpMethod.resolve(req.getMethod());
if(httpMethod==HttpMethod.PATCH || httpMethod==null){
processRequest(req,res);
}else{
super.serrvice(req,res);
}
...
}
protected final void processRequest(req,res){
...
try{
doService(req,rest);
}catch...
}
protected abstract void doService(req,res){
throws Exception;
}
}
class DispatcherServlet{
@Override
protected void doService(req,res){
...
try{
//分发
doDispatch(req,res);
}finally{
...
}
}
protected void doDispatch(req,res){
HttpServletRequest processRequest=req;
HandlerExecutionChain mappedHandler=null;
boolean multpartRequestParsed=false;
...
try{
ModelAndView mv=null;
...
try{
//检查请求是否是二进制请求
processedRequest=chekMultipart(req);
multipartRequestParsed=(processedRequest!=req);
//根据请求获取Handler
mappedHandler=getHandler(processedRequest);
//Handler为空判断
if(mappedHandler == null){
noHandlerFound(processedRequest,res);
return;
}
//根据Handler获取HandlerAdapter
HandlerAdapter ha=getHandlerAdapter(mappedHandler.getHandler());
String method=req.getMethod();
...
//执行拦截器
if(!mappedHandler.applyPreHandler(processedRequest,res)){
return;
}
//执行Hanlder
mv=ha.handle(processedRequest,res,mappedHandler.getHandler());
}
}
}
//获取Handler
//handlerMappings来自于jar包中的DispatcherServlet.properties
@Nullable
private List<HandlerMapping> handlerMappings;
@Nullable
protected HandlerExecutionChain getHandler(req){
if(this.handlerMappings!=null){
//遍历HandlerMapping
//因为有不同方式注册的Handler,所以存在多个HandlerMapping
//可以通过@Controller注册
//也可以通过@WebServlet+extends HttpServlet注册
//还可以通过@Component+implements Controller注册
for(HandlerMapping hm:this.handlerMappings){
...
//将获取Handler,并将其封装到HandlerExecutionChain
HandlerExecutionChain handler=hm.getHandler(req);
if(handler!=null){
return handler;
}
}
}
return null;
}
//获取HandlerAdapter
//handlerAdapters的值来自于jar包中的DispatcherServlet.properties
@Nullable
private List<HandlerAdapter> handlerAdapters;
protected HandlerAdapter getHandlerAdapter(Object handler){
if(this.handlerAdapters!=null){
//遍历HandlerAdapter
//因为有不同方式注册的Handler,所以存在多个HandlerAdapter
for(HandlerAdapter ha:this.handlerAdapters){
...
//匹配Handler
if(ha.support(handler){
return ha;
}
}
}
}
}
//执行Handler
//执行mappedHandler.getHandler()
class HandlerExecutionChain{
...
//
public Object getHandler(){
return this.handler;
}
}
//执行Handler
//执行ha.handle(processedRequest,res,mappedHandler.getHandler())
//如果自定义的Handler是通过implements Controller注册的话
//则强制转换成Controller接口,向下转型执行自定义的Handler中的方法
class SimpleControllerHanderAdapter{
...
@Override
@Nullable
public ModelAndView handle(req,res,Object handler){
return ((Controller)handler).test(req,res);
}
}
//如果自定义的Handler是通过@Controller注册的话
class AbstractHandlerMethodAdapter{
@Override
@Nullable
public final ModelAndView(req,res,Object handler){
return handlerInternal(req,res,(HandlerMethod)handler);
}
}
class RequestMappingHandlerAdapter{
@Override
protected ModelAndView handlerInternal(req,res,HandlerMethod handlerMethod){
ModelAndView mav;
checkRequest(req);
...
else{
mav=invokeHandlerMethod(req,res,handlerMethod);
}
}
@Nullable
protected ModelAndView invokeHandlerMethod(req,res,handlerMethod){
...
}
}
3.SpringMVC有哪些重要的组件?
- 前端控制器DispatcherServlet:相当于转发器
- 处理器映射器HandlerMapping:根据请求url查找对应的处理器Handler
- 处理器执行链HandlerExecutionChain:处理器执行链
- 处理器适配器HandlerAdapter:处理器Handler需要遵循的规范
- 具体的处理器Handler:程序员开发的具体处理器(Controller类)
- 视图解析器ViewResolver:对视图View进行解析
- 具体的视图View:程序员开发的具体视图(如jsp、pdf等)
为什么SpringMVC底层通过反射获取Handler的单元方法?
- DispatcherServlet不能使用new
- 通过@Controller获取的Handler不是Servlet子类,所以不能转发和重定向
- 只能使用反射