SpringMVC处理请求

﹏ヽ暗。殇╰゛Y 2022-05-30 11:07 473阅读 0赞

HttpServletBean

这里写图片描述
从HttpServletBean的结构中可知,其没有重写service,doXXX等处理请求方法,所以HttpServletBean没有具体处理请求

FrameworkServlet

这里写图片描述
FrameworkServlet重写了HttpServlet的这些方法
这里写图片描述
可以看到Service之中将除了PATCH方法的所有请求都集中到processRequest中进行处理。
这和HttpServlet将不同请求按类型分到不同的方法中正好相反。为什么要这么做?其实SpringMVC对不同类型的请求划分的很好,这里只是应该有其他的事情要做,并且将结构分得更为清晰。先看processRquest
这里写图片描述
这里写图片描述
核心的是doService()模板方法,这个方法在DispatchServlet中实现。在doService前后还做了一些事情,这个就是装饰器设计模式。
在doService()之前是将请求之前的LocaleContext和RequestAttribute保存,然后获取当期请求的LocaleContext和RequestAttribute并设置上,doService()处理之后在finally中使用resetContextHolder再进行恢复。
最后发送一个ServletRequestHandledEvent。

LocaleContextHolder、RequestAttributesHolder

LocaleContext中存放的是本地化信息
这里写图片描述
这里写图片描述
这里写图片描述
首先要提到的一点是LocaleContextHolder是个abstract类,其中的所有方法都是static方法,可以直接调用,而且没有父类也没有子类。也即是不能对其进行实例化,只能调用其中的方法,这种设计是值得学习的。(ps:我通常写Django代码的时候写了很多的工具函数,其实没有做过封装,是很不好的。)

在LocaleContextHolder中封装了两个属性
这里写图片描述
都是ThreadLocal类型的,第二个可以被子线程继承,关于ThreadLocal可以参考:

另外LocalContextHolder提供了get/setLocal方法
这里写图片描述

举个例子程序中如果要使用到Locale的时候首先可以从request中获取,request.getLocale(),但是如果是在Service层中的话就没有request对象了,需要Controller将request传进来。这个就太麻烦了,而且需要修改Service层的接口。这个时候可以直接使用LocaleContextHolder.getLocale()获取Locale对象

RequestAttributes是Spring的一个接口
这里写图片描述
通过RequestAttributes可以get/set/removeAttributes,根据scope参数判定是操作的reques还是session
FrameworkServlet使用的是ServletRequestAttributes,看下其set方式(get/remove类似)
这里写图片描述
这里判定了一个属性isRequestActive(),当调用了requestComplete()方法后request的requestActive就变成了false,可以参看FrameworkServlet中finally中的调用。其实很容易立即,request执行完毕之后就是非active的了。
这里提出一个问题:我想Attributes应该是个Map属性,用来设置key-value,但是一直没有找到这个属性,在HttpServletRequest中没有找到,具体存储在哪里现在还不知道。。
这里写图片描述

在说一下RequestAttributesHolder,其和LocaleContextHolder的设计类似:
这里写图片描述
这里写图片描述
同样的可以在Service层中通过RequestAttributesHolder获取Request

  1. HttpServletRequest req = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
  2. HttpServletResponse resp = ((ServletWebRequest)RequestContextHolder.getRequestAttributes()).getResponse();

可以参考Spring MVC 中几种获取request和response的方式

publishRequestHandledEvent

在FrameworkServlet中的finally中调用了:
这里写图片描述
这里写图片描述
当publishEvent为true的时候就发送消息,在web.xml中publishEvent的配置默认为true。
对于监听这个消息值需要继承ApplicationListener接口,并实现onApplicationEvent方法
对于使用参考下这篇文章:利用spring的ApplicationListener监听某一类事件的发生

DispatchServlet

DispatchServelet是SpringMVC的核心类,所有的顶层设计都在这里。
通过之前的分析可以知道DispatchServlet中执行处理方法的入口是doService
这里写图片描述
设置属性中前面4个和Handler/View有关,后面的三个属性和flashMap有关,主要用与Redirect转发时参数的传递。具体之后研究

由上述代码可知doService()将具体的工作转发给了doDispatch()

这里写图片描述
这里写图片描述

发表评论

表情:
评论列表 (有 0 条评论,473人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Springmvc请求处理

    在上两篇中,我们简单的介绍了web模式下bean的注入以及ioc容器的创建时间。那么,在容器创建之后,servletContext会持有ioc容器,以便在后面去处理业务逻辑

    相关 SpringMVC处理ajax请求

    由于之前我写过几篇关于如何搭建SpringMVC项目的日志,故在本文中不在写各种配置怎么写。只写涉及到处理ajax请求的代码。如果有想了解SpringMVC项目怎么搭建的朋友,

    相关 springmvc异步处理请求

    有两种情况,第一种是业务逻辑复杂,但不需要业务逻辑的结果,第二种是需要返回业务逻辑的处理结果 第一种比较简单,利用多线程处理业务逻辑,或者利用spring中@Asyn注