SpringMvc笔记

Servlet相关内容

web服务器:把资源映射成url,可供公网访问。
那是如何做到映射关系? 实现方式很多,所以出现了servlet规范
处理流程:

1、接收请求
2、处理请求
3、响应请求
以tomcat为例:
tomcat,既是 web服务器,又是servlet容器。
tomcat将步骤 1 的请求封装为ServletRequest ,将步骤 3 的响应封装成 ServletResponse ,将容器封装为类ServletContext

Servlet 规范 javaWeb的核心规范(相当于接口定义)
在这里插入图片描述
上图就是java对servlet的定义,相当于生命周期:
创建 一般由servlet容器实现,tomcat
初始化 init 方法,
ServletConfig :封装了servlet的参数信息,从web.xml中获取,init-param
ServletRequest:http请求到了tomcat后,tomcat通过字符串解析,把各个请求头(header),请求地址(URL),请求参数(queryString)都封装进Request。
ServletResponse:Response在tomcat传给servlet时还是空的对象,servlet逻辑处理后,最终通过response.write()方法,将结果写入response内部的缓冲区,tomcat会在servlet处理结束后拿到response,获取里面的信息,组装成http响应给客户端
service方法: 处理请求逻辑
destroy方法:并不是销毁servlet的方法,而是销毁servlet前一定会调用的方法。默认空实现,可以借此关闭一些资源

GenericServlet 这个类,模版方法,主要就是将 ServletConfig对象从局部变量变成全局变量。
在这里插入图片描述

HttpServlet 继承了 GenericServlet 类,实现了service方法。
(自定义的servlet 一般继承 HttpServlet)

http里面最核心的几种请求类型:
在这里插入图片描述
关于web.xml文件,tomcat自带web.xml文件,
所以这时候需要了解下下面3个概念:
DispatcherServlet springmvc的处理器
DefaultServlet(默认的,缺省):兜底,一般处理静态资源
jspServlet jasper 处理.jsp

在tomcat自带的web.xml 文件中配置了
在这里插入图片描述
在这里插入图片描述
前端控制器 配置 url_pattern
/ 拦截所有请求,会过滤 .jsp,不能访问
/* 拦截所有请求,包括.jsp
但是都不能访问静态资源,如果需要访问静态资源,那就需要交给 DefaultServlet 来处理,前端过滤器 需要配置特定规则,例如 *.xxx 。

classpath: class路径 (不找jar包)
classpath*:

Tomcat架构
通过观察 server.xml 可以得出,容器的包含关系为
Server —> Service --> Connector(监听socket) 或 Engine -->Host (appBase对应具体的Servlet项目)
然后 tomcat默认提供了一个web.xml文件 ,里面配置了两个 servlet ,就是上面说到的
jspServlet 和 DefaultServlet 。

这些代码在Tomcat 类 中 的具体提现为
Server : StandardServer
Service : StandardService
Engine : StandardEngine (Container)
Host : StandardHost
servlet : StandardContext

从tomcat初始化servlet并结合Spring和springMvc流程分析

tomcat初始化的流程我就简单说一下,有些细节等我出tomcat的笔记在写。
大家有兴趣的话可以按照我的方法自己打个断点看看。
写个简单的案例(这个跟tomcat的启动方式有关,内嵌tomcat)
在这里插入图片描述
上图中重点关注addWebapp 和 start 方法

addWebapp方法:

1、创建StandardServer对象
2、创建StandardService对象,并放入 StandardServer中
3、创建StandardEngine对象,并放入 StandardServer中
4、创建StandardHost 对象,并放入 StandardEngine 中
5、获取StandardHost对象中默认的configClass属性,并且基于反射创建出监听器 ContextConfig![在这里插入图片描述](https://img-blog.csdnimg.cn/20201127152127647.png#pic_center)
6、创建StandardContext 对象,并将添加监听器 ContextConfig,并将StandardContext添加到StandardHost对象中

start方法(LifecycleBase中):

1、StandardServer

在这里插入图片描述
上面圈起来的是个抽象方法,点进去找到 StandardServer 的 startInternal() 方法,这里也许有人会问,startInternal();是个抽象方法,为什么是去找 StandardServer 这个子类,而不是其他子类,这时候需要 回顾下 this指针咯,第一次调用start方法的就是StandardServer,所以this指针存的就是 StandardServer的地址,最后调用的抽象方法自然就是 StandardServer的startInternal();方法(这是内嵌tomcat的方式,如果是tomcat原生的做法是,会指定哪个子类的)。

2、StandardService

后面就是类似责任链模式了,会依次调用Lifecyclebase的子类的 startInternal 方法。

StandardService的startInternal方法:
在这里插入图片描述
在这里插入图片描述
源码的注释也已经非常明细了,第一步启动默认的Container容器(engine),第二步就是启动默认的监听端口了。

3、StandardEngine

调用了父类ContainerBase的startInternal方法,回到StandardHost中
在这里插入图片描述

4、StandardHost

和 StandardEngine 逻辑差不多,都是调用了父类ContainerBase的startInternal方法,这回是到了StandardContext中

5、StandardContext

启动Container容器过程中,调用了StandardContext的startInternal方法,这里主要功能有3个

5.1 触发监听

监听器模式
找到ServletConfig类,这里面最核心的还是 webConfig()方法,看源码注释也可以知道分为9大步骤,主要解析web.xml,合并等等
将
在这里插入图片描述
在这里插入图片描述
之所以会解析web.xml,这里配置了。解析成为了url对象,最后生成WebXml对象。

在这里插入图片描述
上面这第三步也是很重要第,主要是和SPI机制有关系了。
在这里插入图片描述在这里插入图片描述在这里插入图片描述
上面几段代码说明了tomcat定义的SPI机制 需要找哪个相对路径下面的哪个类。

最后会将ServletContainerInitializers的实现类都存到StandardContext的initializers 全局变量中。

在这里插入图片描述
上面这部主要就是把web.xml里面配置的servlet,filter 放到 servletContenxt上下文中,将servlet封装成了wapper,并且放入到StandardContext中

5.2 执行onStartup方法

然后通过 下图方法执行 onStartup方法
在这里插入图片描述

5.3 listenerStart() 监听器模式

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
上面就是开始创建父容器了。

5.3.1 父子容器概念

在这里插入图片描述
spring.xml 就是用来生成父容器的
component-scan exclude排除 controller
spring-servlet.xml就是用来生成子容器的
component-scan include只包含 controller
这种配置是估计现在都不用了,现在都用的是springboot,但是拿这种配置来说父子容器很容易理解。
但是为什么要分成两种容器尼,原因就是web框架有很多,不止springMvc一种,如果分了父子容器,方便切换。
因为只有一个配置文件的话,web框架的一些配置 会和 spring的配置 混合在一起,到时候切换web框架的时候配置文件不好修改。
在这里插入图片描述
在这里插入图片描述

创建容器父容器 XmlWebApplicationContext
在这里插入图片描述

5.4 filterStart() 启动过滤器
5.5 loadOnStartup(findChildren()) 加载servlet

在这里插入图片描述
这个方法就是要开始初始化servlet了,
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
开始初始化前端控制器 并创建子容器
在这里插入图片描述
上面的就是创建子容器
在这里插入图片描述
这里是初始化前端控制器9大组件。
我这里主要就说下initHandlerMapping();

这里的初始化逻辑很简单,仅仅是在ApplicationContext中找到所有的handlerMapping,并保存起来。每个组件都对应一个成员变量。

至于这些子类对象是何时定义的。这里需要了解一下spring初始化流程了,这方面我会在spring的笔记中写清楚,大致的就是 利用了 InitializingBean和 ServletContextAware的 原理,
在这里插入图片描述

找到实现类AbstractHandlerMethodMapping ,从这个类开始看,很快能明白了。基本上就是 判断是否存在 注解,是的话就是处理器
在这里插入图片描述
在这里插入图片描述

开始SpringMvc分析

上面的分析尼,基本是基于xml的方式,现在基本上配置springmvc用的是javaConfig的方式来的,那一共有几种配置方式呢?
1、WebMvcConfigurer接口
2、WebMvcConfigurerAdapter
3、WebMvcConfigurationSupport
4、@EnableWebMvc

注:@EnableWebMvc 和 WebMvcConfigurationSupport 会导致springboot的自动状态失效。
原因 WebMvcAutoConfiguration 类上的注解
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

**处理器:**就是我们定义的Controller
**HandlerMapping:**处理器映射器
**HandlerAdapters:**处理器适配器

doDispatch流程

1、根据请求获取处理器和拦截器链

HandlerExecutionChain
在这里插入图片描述
上面是获取到执行链,下面就是根据获取到的处理器找到对应的适配器
在这里插入图片描述
在这里插入图片描述
上面画框是最基本的几种处理器,有人会问
在这里插入图片描述
上面是四种适配器,对应4种处理器。
这里说的处理器和适配器 是在 初始化9大组件的时候 存入的。

1.1 根据url找到对应的处理器流程

因为现在一般都是用@Controller来定义的,所以@Controller定义的处理器都会在 RequestMappingInfoHandlerMapping的mappingRegistry属性中。这些属性的值是在spring容器启动的时候初始化的AbstractHandlerMethodMapping ,利用的是InitializingBean 原理
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
注释说,根据请求找到最匹配的处理器方法。
实际上最主要的是下面这段代码,根据url找到对应的method
在这里插入图片描述
在这里插入图片描述

2、执行拦截器的拦截前方法

下面是执行拦截器的拦截前方法
在这里插入图片描述
如果失败,则会执行拦截后方法,如下图

在这里插入图片描述

3、执行处理器方法

下面就是会调用到我们定义的controller方法了
在这里插入图片描述

4、执行拦截器的拦截中方法

在这里插入图片描述

5、渲染视图

在这里插入图片描述

Url匹配规则在Mapper类的internalMapWrapper方法中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值