::: warning 知识点
addMatchingMappings方法 , 主要一个匹配过程 , 匹配 @RequestMapping注解中的属性值是否满足
/** consumes:指定处理请求的提交内容类型(Content-Type) , *例如application/json, text/html;* produces: 指定返回的内容类型 , 仅当request请求头中的(Accept)类型中包含该指定类型才返回;* params:指定request中必须包含某些参数值是 , 才让该方法处理 。* headers:指定request中必须包含某些指定的header值 , 才能让该方法处理请求 。* */@RequestMapping(value = https://www.isolves.com/it/cxkf/kj/2020-10-10/"/getUser",method = RequestMethod.GET,params = "username=jack",consumes = "application/json",produces = "application/json",headers = "Referer=http://www.xx.com/"):::
返回 getHandler , 进入 getHandlerExecutionChain方法
所在类:org.springframework.web.servlet.handler. AbstractHandlerMapping
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {// 如果没有获得则创建一个 HandlerExecutionChainHandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));// 获取当前的请求地址:/user/xxxString lookupPath = this.urlPathHelper.getLookupPathForRequest(request);// 在 HandlerExecutionChain 中添加拦截器// 遍历 SpringMVC 容器的所有拦截器for (HandlerInterceptor interceptor : this.adaptedInterceptors) {// 判断拦截器类型 , 如果是 MappedInterceptor 类型if (interceptor instanceof MappedInterceptor) {MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;// 则先匹配路径后再添加到执行链if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {chain.addInterceptor(mappedInterceptor.getInterceptor());}}else {// 否则直接添加到执行链chain.addInterceptor(interceptor);}}return chain;}::: warning 知识点getHandlerExecutionChain中的 HandlerInterceptor拦截器是 SpringMVC中的 , SpringAOP中的拦截器是 MethodInterceptor 。:::
拿到当前请求对应的 handler后 ,
返回主流程 , 进入 getHandlerAdapter方法
所在类:org.springframework.web.servlet. DispatcherServlet
/** * TODO : 根据 handlerMethod对象 , 找到合适的 HandlerAdapter对象 , 这里用到了策略模式 */protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {if (this.handlerAdapters != null) {for (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(handler)) {// 返回一个可以支持的HandlerAdapter 处理程序实例return adapter;}}}throw new ServletException("No adapter for handler [" + handler +"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");}::: warning 知识点HandlerAdapter 是什么HandlerAdapter是一个接口 , 充当自身与处理程序对象之间的桥梁 , 从而导致松散耦合设计 。HandlerAdapter主要处理方法参数、相关注解、数据绑定、消息转换、返回值、调用视图解析器等 。:::
RequestMappingHandlerMapping为当前的请求找到合适的处理程序方法 。
RequestMappingHandlerAdapter执行这个处理程序方法 , 并为它提供反射调用所需要的参数 。
HandlerAdapter UML 图
HandlerAdapter的4个实现类:
SimpleServletHandlerAdapter: 适配实现 Servlet 接口的 Handler, 默认调用其 service方法
SimpleControllerHandlerAdapter: 适配实现 Controller 接口的 Handler, 默认调用其 handleRequest 方法
HttpRequestHandlerAdapter: 适配实现 HttpRequestHandler 接口的 Handler, 默认调用其 handleRequest 方法
RequestMappingHandlerAdapter: 适配被 @RequestMapping注释的方式, 一般都是解析一个一个参数, 并且通过反射进行激活
HandlerAdapter 总结HandlerAdapter 是 SpringMVC中扩展机制的非常好的一个体现, , 通过 HandlerAdapter这种设计模式 , DispatcherServlet 就可以支持任何格式的 Handler(这里的可以支持指在不改变 DispatcherServlet 的情况下) , 第二是 HandlerAdapter 基于不同 Handler实现不同实现类(策略模式) , 最后也是最重要的就是参数的解析与返回值的解析 。
::: danger 为什么要用HandlerAdapter适配器模式? 首先 , Controller的定义有多种 , 一种是带 @Controller注解的 , 还可以写一个 servlet 当做 controller, 所以用适配器做适配 , 不同子类实现 HandlerAdapter接口 , 定义自己的业务逻辑 , 每个子类都是适配某一种类型的控制器 , 有了 HandlerAdapter , 你只需要调用自己实现的 handle方法 , 屏蔽了不一致的细节 , 对用户来说直接找到对应的处理方法 , 无须关系哪个实现方法 , 否则只能在 DispatcherServlet里面通过 if、 else来处理了 。:::
推荐阅读
- Spring Security 中如何细化权限粒度?
- springcloud微服务架构开发实战:分布式消息总线
- 怎么理解Laravel的核心架构
- 原来这才是Spring Boot使用AOP的正确姿势
- 使用spring cache让我的接口性能瞬间提升了100倍
- Springboot 实现数据库备份还原
- 微服务架构图
- 全网最全一篇数据库MVCC详解,不全你打我
- SpringCloud开发框架入门知识
- SpringMVC:进阶
