spring-06 springmvc设计思想与体系结构

文章目录

  • 1.servlet 与jsp 执行过程
  • 2.spring mvc 执行
    • 2.1 spring mvc 执行流程
    • 2.2 spring mvc 体系结构
    • 2.3 实现简单spring mvc
      • 2.3.1 项目依赖
      • 2.3.2 web.xml
      • 2.3.3 spring-mvc.xml
      • 2.3.4 创建controller
      • 2.3.5 运行jeety
    • 2.4 体系结构UML
  • 3.mvc 执行流程解析
    • 3.1 mvc 各组件执行流程
    • 3.2 HandlerMapping 详解
      • 3.2.1 HandlerMapping 接口方法
      • 3.2.2 HandlerMapping 接口结构
        • 3.2.2.1 BeanNameUrlHandlerMapping 使用(4.1 以后不支持)
    • 3.3 HandlerAdapter详解
      • 3.3.1 HandlerAdapter 接口方法
      • 3.3.2 HandlerAdapter 接口结构图
      • 3.3.3 基于Servlet处理SimpleServletHandlerAdapter(4.1 以后不支持)
    • 3.4 ViewResolver 与View 详解
    • 3.5 HandlerExceptionResolver详解
      • 3.5.1 使用
    • 3.6 HandlerInterceptor 详解
      • 3.6.1 演示
  • 4.注解配置
    • 4.1 实现
    • 4.2 为什么基于 配置就能实现mvc 的整个配置了,之前所提到的 handlerMapping 、与handlerAdapter 组件都不适用了?

1.servlet 与jsp 执行过程

spring-06 springmvc设计思想与体系结构_第1张图片
流程说明:

  1. 请求Servlet
  2. 处理业务逻辑
  3. 设置业务Model
  4. forward jsp Servlet
  5. jsp Servlet 解析封装html 返回

2.spring mvc 执行

spring mvc本质上还是在使用Servlet处理,并在其基础上进行了封装简化了开发流程,提高易用性、并使用程序逻辑结构变得更清晰

  • 基于注解的URL映谢
  • http表单参数转换
  • 全局统一异常处理
  • 拦截器的实现

2.1 spring mvc 执行流程

spring-06 springmvc设计思想与体系结构_第2张图片

2.2 spring mvc 体系结构

  • HandlerMapping:
    url与控制器的映谢
  • HandlerAdapter:
    控制器执行适配器
  • ViewResolver:
    视图仓库
  • view:
    具体解析视图
  • HandlerExceptionResolver:
    异常捕捕捉器
  • HandlerInterceptor:
    拦截器

2.3 实现简单spring mvc

2.3.1 项目依赖



    
        spring-study
        com.myx
        1.0-SNAPSHOT
    
    4.0.0
    jar
    spring-mvc
    
        
            org.springframework
            spring-webmvc
            ${spring.version}
        
        
            javax.servlet
            javax.servlet-api
            3.1.0
        
        
            javax.servlet
            jstl
            1.2
        
        
            taglibs
            standard
            1.1.2
        
    
    
        
            
                org.mortbay.jetty
                jetty-maven-plugin
                7.4.5.v20110725
                
                    
                        /
                    
                    3
                    
                        
                            src/main/webapp
                            
                                **/*.xml
                            
                        
                    
                    
                        
                            8081
                            400000
                        
                    
                
            
        
    

2.3.2 web.xml

spring-06 springmvc设计思想与体系结构_第3张图片



    
    spring-mvc
    
        dispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            
                classpath:/spring-mvc.xml
            
        
    
    
        dispatcherServlet
        /
    

    
        /index.html
    


2.3.3 spring-mvc.xml




    
    

    
    
        
            
                simpleController
            
        
    

    
    

    
    
        
        
        
    

2.3.4 创建controller

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 描述:简单路由映射实现mvc
 * @author: myx
 * @date: 2019/1/14
 * Copyright © 2018-hotpot. All rights reserved.
 */
public class SimpleController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv = new ModelAndView("userView");
        mv.addObject("name", "myx is good man");
        return mv;
    }
}

2.3.5 运行jeety

spring-06 springmvc设计思想与体系结构_第4张图片
spring-06 springmvc设计思想与体系结构_第5张图片

2.4 体系结构UML

spring-06 springmvc设计思想与体系结构_第6张图片

3.mvc 执行流程解析

3.1 mvc 各组件执行流程

spring-06 springmvc设计思想与体系结构_第7张图片

3.2 HandlerMapping 详解

其为mvc 中url路径与Control对像的映射,DispatcherServlet 就是基于此组件来寻找对应的Control,如果找不到就会报Not Found mapping 的异常。

3.2.1 HandlerMapping 接口方法

在这里插入图片描述

3.2.2 HandlerMapping 接口结构

spring-06 springmvc设计思想与体系结构_第8张图片

目前主流的三种mapping:

  • BeanNameUrlHandlerMapping: 基于ioc name 中已 “/” 开头的Bean时行 注册至映谢.
  • SimpleUrlHandlerMapping:基于手动配置 url 与control 映谢
  • RequestMappingHandlerMapping:基于@RequestMapping注解配置对应映谢

3.2.2.1 BeanNameUrlHandlerMapping 使用(4.1 以后不支持)




import org.springframework.web.HttpRequestHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 描述:BeanNameUrlHandlerMapping 测试
 * @author: myx
 * @date: 2019/1/14
 * Copyright © 2018-hotpot. All rights reserved.
 */
public class BeanNameController implements HttpRequestHandler {
    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.getWriter().println("myx is good man");
    }
}

3.3 HandlerAdapter详解

这里spring mvc 采用适配器模式来适配调用指定Handler,根据Handler的不同种类采用不同的Adapter,其Handler与 HandlerAdapter 对应关系如下:

Handler类别 对应适配器 描述
Controller SimpleControllerHandlerAdapter 标准控制器,返回ModelAndView
HttpRequestHandler HttpRequestHandlerAdapter 业务自行处理 请求,不需要通过modelAndView 转到视图
Servlet SimpleServletHandlerAdapter 基于标准的servlet 处理
HandlerMethod RequestMappingHandlerAdapter 基于@requestMapping对应方法处理

3.3.1 HandlerAdapter 接口方法

在这里插入图片描述

3.3.2 HandlerAdapter 接口结构图

spring-06 springmvc设计思想与体系结构_第9张图片

3.3.3 基于Servlet处理SimpleServletHandlerAdapter(4.1 以后不支持)







import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.getWriter().println("hello luban ");
    }
}

3.4 ViewResolver 与View 详解

找到应的Adapter 之后就会基于适配器调用业务处理,处理完之后业务方会返回一个ModelAndView ,在去查找对应的视图进行处理。其在org.springframework.web.servlet.DispatcherServlet#resolveViewName() 中遍历 viewResolvers 列表查找,如果找不到就会报一个 Could not resolve view with name 异常。
spring-06 springmvc设计思想与体系结构_第10张图片

在下一步就是基于ViewResolver.resolveViewName() 获取对应View来解析生成Html并返回 。对应VIEW结构如下:
spring-06 springmvc设计思想与体系结构_第11张图片
至此整个正向流程就已经走完了,如果此时程序处理异常 MVC 该如何处理呢?

3.5 HandlerExceptionResolver详解

该组件用于指示 当出现异常时 mvc 该如何处理。 dispatcherServlet 会调用org.springframework.web.servlet.DispatcherServlet#processHandlerException() 方法,遍历 handlerExceptionResolvers 处理异常,处理完成之后返回errorView 跳转到异常视图。

3.5.1 使用




import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 描述:异常
 * @author: myx
 * @date: 2019/1/14
 * Copyright © 2018-hotpot. All rights reserved.
 */
public class SimpleExceptionHandle implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        return new ModelAndView("error");
    }
}

3.6 HandlerInterceptor 详解

除了上述组件之外 spring 中还引入了 我Interceptor 拦截器 机制,类似于Filter。

3.6.1 演示




import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 描述:拦截器
 * @author: myx
 * @date: 2019/1/14
 * Copyright © 2018-hotpot. All rights reserved.
 */
public class SimpleHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

其实现机制是基于 HandlerExecutionChain 分别在 doDispatch 方法中执行以下方法:

  • preHandle :业务处理前执行
  • postHandle:业务处理后(异常则不执行)
  • afterCompletion:视图处理后

具体逻辑源码参见:org.springframework.web.servlet.DispatcherServlet#doDispatch 方法。

4.注解配置

4.1 实现




    
    
    
    
    
        
        
        
    

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * 描述:注解实现
 * @author: myx
 * @date: 2019/1/14
 * Copyright © 2018-hotpot. All rights reserved.
 */
@Controller
public class SimpleController{
    /**
     * 注解方法
     * @return
     */
    @RequestMapping("/hello.do")
    public ModelAndView hello() {
        ModelAndView mv = new ModelAndView("userView");
        mv.addObject("name", "myx 注解");
        return mv;
    }
}

在这里插入图片描述

4.2 为什么基于 mvc:annotation-driven/ 配置就能实现mvc 的整个配置了,之前所提到的 handlerMapping 、与handlerAdapter 组件都不适用了?

只要查看以类的源就可以知晓其中原因:

  • 认识 NamespaceHandler 接口
  • 查看 MvcNamespaceHandler
  • 查看AnnotationDrivenBeanDefinitionParser

结论:
对应的解析器,自动向ioc 里面注册了两个BeanDefinition。分别是:RequestMappingHandlerMapping与BeanNameUrlHandlerMapping

你可能感兴趣的:(spring,spring,springmvc)