SpringMVC中的设计模式——责任链模式

定义: 

使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

优点:


将请求者和处理者分开,两者解耦,提供系统灵活性

角色:

1、抽象处理者(Handle):定义一个处理请求的接口。如果需要可以定义出一个方法以设定和返回

对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。

图中的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。

2、具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择请求处理掉,或者将请求传给下家

。由具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

上图中的示意性的具体处理者ConcreteHandler类只有handleRequest()一个方法。

责任链模式的静态类结构如下图:

应用:

在 Spring MVC 的 HandlerExecutionChain

  • HandlerExecutionChain 本身不会执行 interceptor 的逻辑,只是将请求分配给 chain 上注册的 interceptor 执行;
  • HandlerExecutionChain 维护了 HandlerInterceptor 的集合

在 Spring MVC 的 DispatcherServlet 类中,有如下的主要代码逻辑:
  doDispatch方法中,构建了 interceptor 执行链,将请求分配给 preHandle 执行,当 preHandle 方法返回为 false时,会调用到 afterCompletion 执行,最后调用 postHandle 方法。


源码如下:

protected void doDispatch (HttpServletRequest request, HttpServletResponse response) throws Exception {
            HandlerExecutionChain mappedHandler = null;
            mappedHandler = getHandler(processedRequest);
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return;
            }
           //当上面的 applyPreHandle 返回false时,继续向下执行到
            mappedHandler.applyPostHandle(processedRequest, response, mv);
}


//调用拦截器的 interceptor.preHandle
boolean applyPreHandle (HttpServletRequest request, HttpServletResponse response) {
    HandlerInterceptor[] interceptors = getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = 0; i < interceptors.length; i++) {
            HandlerInterceptor interceptor = interceptors[i];
            if (!interceptor.preHandle(request, response, this.handler)) {
                triggerAfterCompletion(request, response, null);
                return false;
            }
            this.interceptorIndex = i;*}
    }
    return true;
}
void triggerAfterCompletion (HttpServletRequest request, HttpServletResponse response,Exception ex){
     HandlerInterceptor interceptor = interceptors[i];
     try {
         interceptor.afterCompletion(request, response, this.handler, ex);
     }
 }
        
//调用拦截器的 interceptor.postHandle
void applyPostHandle (HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv){
    HandlerInterceptor interceptor = interceptors[i];
    interceptor.postHandle(request, response, this.handler, mv);
}

参考:

SpringMVC的执行流程

1、首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;

2、DispatcherServlet——>HandlerMapping, HandlerMapping 将会把请求映射为HandlerExecutionChain 对象(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略;

3、DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;

4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名);

5、ModelAndView的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;

6、View——>渲染,View会根据传进来的Model模型数据进行渲染(将数据添加到页面),此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;

7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。


SpringMVC更多详情请查看

发布了129 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41808387/article/details/104718963