SpringMVC-1.5-运行原理

SpringMVC-1.5-运行原理

前言

  • 首先,来看一下 SpringMVC 的整个请求流程,如下图:

SpringMVC 整体流程步骤解析:

1,用户去单击了某个请求路径,发起了一个 request 请求,这个请求会被DispatcherServlet 前端控制器处理。

2,前端控制器DispatcherServlet 去请求处理器映射器 HandlerMapping 去查找Handler,可以依据注解或者XML配置去查找。

3,处理器映射器HandlerMapping 根据配置找到相应的 Handler,返回给前端控制器 DispatcherServlet,这个Handler 可能包含 NInterceptor拦截器。

4,前端控制器 DispatcherServlet请求处理器适配器HandlerAdapter 去执行相应的 Handler,也就是 Controller

5,处理器适配器 HandlerAdapter 执行 Handler

6,Handler执行完毕后会返回给处理器适配器HandlerAdapter一个ModelAndView对象,ModelAndViewSpringMVC底层对象,包括 Model数据模型和 View视图信息。

7,处理器适配器HandlerAdapter接收到Handler返回的 ModelAndView 后,将其返回给前端控制器 DispatcherServlet

8,前端控制器 DispatcherServlet 接收到 ModelAndView 后,会请求视图解析器 ViewResolver 对视图进行解析。

9,视图解析器 ViewResolver根据View信息匹配到相应的视图结果,反馈给前端控制器 DispatcherServlet

10,前端控制器DispatcherServlet收到 View 具体视图后,进行视图渲染,将Model中的模型数据填充到View视图中的request域,生成最终的视图 View

11,前端控制器DispatcherServlet向用户返回请求结果。

1. 组件说明

  • 整个处理流程用到的组件有前端控制器 DispatcherServlet、处理器映射器 HandlerMapping、处理器适配器 HandlerAdapter、处理器 Handler、视图解析器 ViewResolver、视图 View。

  • 前端控制器 DispatcherServlet:用来接收用户请求,反馈用户结果。相当于转发器或中央处理器,控制着整个流程的运行,对各个组件进行调度,降低组件之间的耦合性,并且有利于组件之间的扩展。

  • 处理器映射器 HandlerMapping:作用是根据请求的url 路径,通过组件或者是 xml配置的方式,去寻找匹配的处理器Handler信息。

  • 处理器适配器HandlerAdapter:作用是根据映射器找到的处理器 Handler 信息,按照特定的规则去执行相关的处理器Handler。(Controller中的方法)

  • 处理器 Hander:作用是执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装到 ModelAndView对象中。

  • 视图解析器 ViewResolver:作用是进行解析操作,通过 ModelAndView 对象中的 View信息将逻辑视图名解析成真正的视图 View

    • 视图 View:就是不同的 View 类型,例如 JSP。
  • 开发过程中我们需要开发的是 Handler 处理器和 View 视图,但每一步都至关重要,在 SpringMVC 的整个工作流程中,了解它的每一步作用,更有利于日后的学习和理解。

2. 处理器映射器

  • 在 SpringMVC 中,处理器映射器有两种配置方式,一种是基于 XML 的资源配置,也就是常说的非注解方式。另外一种方式是基于 Annotation 注解方式的配置。
  • 注解是代码里的特殊标记,这些标记可以在程序编译、类加载和运行的时候被读取,然后去执行相应的处理。具体使用哪一种配置方式,要根据程序的具体情况而定。

2.1 非注解(不常用)

1,非注解处理器类 BeanNameUrlHandlerMapping,这个类的映射规则是将 bean 的 name 作为 url 进行查找,需要在配置Handler 时指定beanname,其示例代码如下:

1
2
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean name="/test.do" class="com.zhuuu.controller.TestController"/>
  • 这时的 url 地址就会根据 bean 的 name 去查找,也就是示例中配置的 name 的值 test.do,且这个必须以 / 开头。

2,非注解处理器类 SimpleUrlHandlerMapping,它可以通过内部参数去配置请求的 url 和 handler 之间的映射关系,其示例配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="someCheckInterceptor1"/>
<ref bean="someCheckInterceptor2"/>
</list>
</property>
<property name="mapping">
<props>
<prop key="user.action">userController</prop>
<prop key="product.action">productController</prop>
<prop key="other.action">otherController</prop>
</props>
</property>
</bean>
  • 其中 property 属性可以配置 interceptors 拦截器,也可以配置 mapping(Handler 处理器和 url 的映射关系)。

3,非注解处理器类ControllerClassNameHandlerMapping,它是将 Controller 控制器的名字作为映射的 url 地址,例如 TestController 控制器则映射的地址就为/ test*,如果是 test 控制器下的 test 方法,则 url 为 test/test.action,示例代码如下:

1
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

2.2 注解(常用)

  • 注解处理方式不需要在 xml 中进行配置,只需要在指定的地方声明一些注解信息即可。SpringMVC3.1 版本之后默认的处理器映射器是 RequestMappingHandlerMapping,位于 SpringMVC的核心 jar 包 org.springframework.web.servlet.mvc.method.annotation中。

注解配置方式有两种

  • 第一种是在 springmvc.xml中配置,声明相关的 bean和实现即可,示例代码如下:
1
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
  • 第二种是使用 <mvc:annotation-driven/> 标签来配置,这个标签是一种简写方式,它会自动去注册处理器映射器,配置示例如下:
1
<mvc:annotation-driven></mvc:annotation-driven>

当使用了注解方式后,就不需要在 xml 配置中配置任何信息了,只需要在作为Handler 处理器的 Java 类中添加相应的注解即可,示例如下:

1
2
3
4
5
6
7
8
//使用Controller来标识它是一个控制器
@Controller
public class TestControllerTest{
@RequestMapping("/testurl")
public ModelAndView testurl() throws Exception{
//逻辑代码
}
}
  • 在以上代码中 @Controller是注解信息,表示该类是一个控制器类,可以被注解的处理器适配器找到,而 TestControllerTest 类中的testurl方法上有一个 @RequestMapping注解信息,作用是指定一个url与该方法绑定。

  • 这时为了让注解的处理器映射器能找到 Handler控制器,需要在 springmvc.xml 做下配置,方式有两种:


  1. springmvc.xml中声明 bean 信息,示例代码如下:
1
<bean class="com.zhuuu.controller.TestController"></bean>
  1. 第二种是扫描配置,对某一个包下的所有类进行扫描,找出所有使用 @Controller 注解的 Handler 控制器类,示例代码如下:
1
<context:component-scan base-package="com.fageweiketang.controller"></context:component-scan>

2.3 小结

  • SpringMVC 中处理器映射器HandlerMapping根据配置找到相应的 Handler,返回给前端控制器 DispatcherServlet,这个 Handler可能包含 NInterceptor 拦截器。
  • 其配置方式有两种,一个是非注解方式配置,也就是基于 xml配置文件。第二个就是注解配置,在类中做相应的注解即可。

3. 处理器适配器

  • 处理器适配器 HandlerAdapter:作用是根据映射器找到的处理器Handler 信息,按照特定的规则去执行相关的处理器Handler

  • 其配置方式有两种,一种是基于xml 的资源配置,也就是非注解的配置方式。另外一种就是基于 Annotation注解的配置。其注解在代码中做上特殊标记,这些标记就可以编译、类加载、运行时被读取,然后去执行相应的处理。

3.1 非注解处理器适配器(不用)

  • 第一个是 SimpleControllerHandlerAdapter,翻译过来就是简单的控制器处理器适配器,它支持所有实现了 Controller 接口的 Handler 控制器,如果开发中编写了实现 Controller 接口的控制器,则 SimpleControllerHandlerAdapter 适配器就会去执行 Controller 的具体方法。其配置示例如下:
1
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
  • 第二个是HttpRequestHandlerAdapter,翻译过来就是http 请求处理器适配器,它要求编写的 Handler需要实现 HttpRequestHandler 接口。使用这种 Handler 的开发方式,方便开发者获取 request的相关 http请求信息,以及设置返回对象 response 的一些参数。其配置示例如下:
1
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>

然后在之前的处理器映射器配置中添加这个 Handler 的 url 映射信息,其示例代码如下:

1
2
3
4
5
6
7
8
9
10
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mapping">
<props>
<prop key="/test1.action">testController1</prop>
<prop key="/test2.action">testController2</prop>
</props>
</property>
</bean>
<bean id="testController1" class="com.fageweiketang.controller.TestController1"/>
<bean id="testController2" class="com.fageweiketang.controller.TestController2"/>
  • 处理器映射器就是根据url来查找Handler,处理器适配器就是按照它要求的规则去执行 Handler,但是一个 Handler类中只能编写一个方法,这个弊端就可以通过注解的方式来解决。

3.2 注解处理配适配器

  • 注解处理器适配器,只需要在指定的地方声明一些注解信息即可。在 spring3.1 之后,springmvc 新的基于注解的适配器默认是 RequestMappingHandlerAdapter,它位于 springmvc 核心 jar 包 org.springframework.web.servlet.mvc.method.annotation
  1. 一种方式是在 springmvc.xml 中声明 bean 和实现方式即可,示例代码如下:
1
<mvc:annotation-driven></mvc:annotation-driven>
  1. 第二种方式是使用<mvc:annotation-driven/>标签来配置,它是一种简写模式,它会自动注册处理器适配器,配置方式如下:
1
<mvc:annotation-driven></mvc:annotation-driven>
  • 当我们使用了其注解方式后,就无需在 xml 配置中配置其它任何信息了,而只需要在作为 Handler 处理器的 Java 类中去添加相应的注解即可,示例代码框架如下:
1
2
3
4
5
6
7
8
//使用Controller来标识它是一个控制器
@Controller
public class TestControllerTest{
@RequestMapping("/testurl")
public ModelAndView testurl() throws Exception{
//逻辑代码
}
}
  • 在以上代码中 @Controller 是注解信息,表示该类是一个控制器类,可以被注解的处理器适配器找到,而 TestControllerTest 类中的 testurl 方法上有一个 @RequestMapping 注解信息,作用是指定一个 url 与该方法绑定。

这时为了让注解的处理器映射器能找到 Handler 控制器,需要在 springmvc.xml 做下配置,方式有两种:

1,在springmvc.xml 中声明 bean 信息,示例代码如下:

1
<bean class="com.fageweiketang.controller.TestController"></bean>
  1. 第二种是扫描配置,对某一个包下的所有类进行扫描,找出所有使用 @Controller 注解的 Handler 控制器类,示例代码如下:
1
<context:component-scan base-package="com.zhuuu.controller"></context:component-scan>

3.3 小结

  • SpringMVC 中处理器映射器 HandlerMapping 根据配置找到相应的 Handler,返回给前端控制器 DispatcherServlet,前端控制器再传给处理器适配器让它进行处理,处理器适配器会去找到对应的 Handler 去处理,处理后则就会返回一个 ModleAndView 对象。

  • 其配置方式有两种,一个是非注解方式配置,也就是基于 xml 配置文件。第二个就是注解配置,在类中做相应的注解即可。

注意事项 : / 和 /*的区别

  1. / :只会匹配所有的请求,不会匹配页面(使用这个就行)
  2. /* : 不仅会匹配所有的请求,也会匹配jsp页面
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信