springmvc处理流程

springmvc处理流程_第1张图片
springmvc处理流程图
  • 前端控制器 DispatcherServlet
  • 映射处理器 HandlerMapping
  • 处理器适配器 HandlerAdapter
  • 视图解析器 ViewResolver

核心架构的具体流程步骤如下:

1.用户发送请求——>DispatcherServlet

Dispatcher作为统一的访问点,进行全局的流程控制。

前端控制器收到请求之后自己不进行处理,而是委托给其他解析器进行处理。

【Dispatcher在spring中的代码配置】
  一般来说,DispatcherServlet配置如下:


    dispatcher
    org.springframework.web.servlet.DispatcherServlet
    1


    dispatcher
    /

该DispatcherServlet默认使用WebApplicationContext作为上下文,Spring默认配置文件为“/WEB-INF/[servlet名字]-servlet.xml”。但是DispatcherServlet也可以配置自己的初始化参数,覆盖默认配置:


springmvc处理流程_第2张图片

因此我们可以通过添加初始化参数:


    dispatcher
    org.springframework.web.servlet.DispatcherServlet
    
        contextConfigLocation
        classpath*:applicationContext.xml
    
    1


    dispatcher
    /

使用如上配置,Spring Web MVC框架将加载“classpath*:applicationContext.xml”来进行初始化上下文而不是“/WEB-INF/[servlet名字]-servlet.xml”。

2.DispatcherServlet——>HandlerMapping

HandlerMapping充当着URL和Controller之间映射关系配置的角色,它的工作就是为每个请求找到合适的处理器Handler,也就是定位Controller。

HandlerMapping会把请求映射为HandlerExecutionChain对象
  HandlerExecutionChain是一个很有趣的东西,它包括我们要执行的处理方法(Controller)和一组Interceptor(拦截器,非必须),我们可以把它想象为一个执行request最基本的单元。

【HandlerMapping在spring中的代码配置】
  在Spring中,HandlerMapping有以下4种映射方式。

(1)BeanNameUrlHandlerMapping(默认)
  按照controller的name来映射寻找controlller,它是默认存在的,因此无需在配置文件中配置

  

  

(2)SimplerUrlHandlerMapping
  使用简单url映射,与默认的映射可以各自独立存在。可以使用此映射来分类配置controller和配置url的各自职责。

  
  
  
  
  
      
          
            testController  
          
      
  

(3)ContraollerClassNameHandlerMapping
  这个实际上是去掉控制器中的Controller后,将剩余的部分跟URL匹配,比如,如果不用这个MAPPING的话,要这样搞:

 
   
   
 

用了这个mapping的话可以这样了:

 
   
   
   
 

(4)RequestMappingHandlerMapping
   RequestMappingHandlerMapping ,用于注解@Controller,@RequestMapping来定义controller。RequestMappingHandlerMapping这个类的对象,只能在controller层用,并且要在申明了@RequestMapping的方法里面用。,从RequestMappingHandlerMapping的源码注释里面可以看出:

/** 
 * Creates {@link RequestMappingInfo} instances from type and method-level  
 * {@link RequestMapping @RequestMapping} annotations in  
 * {@link Controller @Controller} classes. 
 * 
 * @author Arjen Poutsma 
 * @author Rossen Stoyanchev 
 * @since 3.1 
 */  
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping {  
//省略  
} 

3、DispatcherServlet——>HandlerAdapter

当HandlerMapping获取到执行请求的Controller之后,需要一个帮助定位具体请求方法的处理类,这个类就是HandlerAdapter。

DispatcherServlte会根据HandlerMapping传过来的controller与已经注册好了的HandlerAdapter一一匹配,看哪一种HandlerAdapter是支持该Controller类型的。HandlerAdapter会检查处理类相应处理方法的参数,确定如何转换需要的参数传入调用方法,以及相关Annotation的配置,最终确定使用处理类的哪个处理方法处理请求。
  采用HandlerAdapter的原因是因为Controller的类型不同,有多重实现方式,调用的方式是不确定的。因此Spring定义了一个适配接口,使得每一个Controller有一种对应的适配器实现类,让适配器代替Controller执行相应的方法。
  如果没有适配器会怎样呢?下面代码是没有经过适配器直接调用Controller:

if(mappedHandler.getHandler() instanceof MultiActionController){  
   ((MultiActionController)mappedHandler.getHandler()).xxx  
}else if(mappedHandler.getHandler() instanceof XXX){  
    ...  
}else if(...){  
   ...  
}  
... 

这样做的后果就是每增加一个Controller,就要在代码中增加一行if(mappedHandler.getHandler() instanceof XXX),代码将难以维护。

但是如果有了适配器就不一样了,看一下代码,不论实现何种Controller,适配器总能经过适配以后得到想要的结果,匹配成功之后右适配器执行对应的Controller对应方法 ,而无需每调用一个Controller就写一次mappedHandler.getHandler() instanceof XXX 。

//定义一个Adapter接口  
public interface HandlerAdapter {  
    public boolean supports(Object handler);  
    public void handle(Object handler);  
}  
  
//以下是三种Controller实现  
public interface Controller {  
  
}  
  
public class HttpController implements Controller{  
    public void doHttpHandler(){  
        System.out.println("http...");  
    }  
}  
  
public class SimpleController implements Controller{  
    public void doSimplerHandler(){  
        System.out.println("simple...");  
    }  
}  
  
public class AnnotationController implements Controller{  
    public void doAnnotationHandler(){  
        System.out.println("annotation...");  
    }  
}  
  
  
//下面编写适配器类  
  
public class SimpleHandlerAdapter implements HandlerAdapter {  
  
  
    public void handle(Object handler) {  
        ((SimpleController)handler).doSimplerHandler();  
    }  
  
    public boolean supports(Object handler) {  
        return (handler instanceof SimpleController);  
    }  
  
}  
  
  
public class HttpHandlerAdapter implements HandlerAdapter {  
  
    public void handle(Object handler) {  
        ((HttpController)handler).doHttpHandler();  
    }  
  
    public boolean supports(Object handler) {  
        return (handler instanceof HttpController);  
    }  
  
}  
  
  
  
public class AnnotationHandlerAdapter implements HandlerAdapter {  
  
    public void handle(Object handler) {  
        ((AnnotationController)handler).doAnnotationHandler();  
    }  
  
    public boolean supports(Object handler) {  
          
        return (handler instanceof AnnotationController);  
    }  
  
}  
  
  
//模拟一个DispatcherServlet  
import java.util.ArrayList;  
import java.util.List;  
  
  
public class DispatchServlet {  
      
    public static List handlerAdapters = new ArrayList();   
      
    public DispatchServlet(){  
        handlerAdapters.add(new AnnotationHandlerAdapter());  
        handlerAdapters.add(new HttpHandlerAdapter());  
        handlerAdapters.add(new SimpleHandlerAdapter());  
    }  
      
      
    public void doDispatch(){  
          
         
   //不论实现何种Controller,适配器总能经过适配以后得到想要的结果  
  // HttpController controller = new HttpController();  
  // AnnotationController controller = new AnnotationController();  
        SimpleController controller = new SimpleController();  
        //得到对应适配器  
        HandlerAdapter adapter = getHandler(controller);  
        //通过适配器执行对应的controller对应方法  
        adapter.handle(controller);  
          
    }  
      
    public HandlerAdapter getHandler(Controller controller){  
        for(HandlerAdapter adapter: this.handlerAdapters){  
            if(adapter.supports(controller)){  
                return adapter;  
            }  
        }  
        return null;  
    }  
      
    public static void main(String[] args){  
        new DispatchServlet().doDispatch();  
    }  
      
}  

HandlerAdapter在spring中的代码配置:

  
 

5.HandlerAdapter——>DispatcherServlet
  HandlerAdapter把ModelAndView(包含模型数据、逻辑视图名)对象传递给DispatcherServlet

6.ModelAndView的逻辑视图名——>ViewResolver
  ViewResolver会将逻辑视图名解析为具体的View。

7.View——>渲染
  View根据传进来的Model数据模型进行渲染,此处的Model实际上是一个Map数据结构。

8.视图处理完毕
  前端控制器DispatcherServlet将收回控制权,然后由DispatcherServlet返回响应给用户。

你可能感兴趣的:(springmvc处理流程)