SpringMVC 笔记篇

1.1 执行流程

1.1.6 BeanNameUrlHandlerMapping ------> /test Bean对象

在1.1.5中我们提到了RequestMappingHandlerMapping这个Bean对象的初始化逻辑,除了这个Bean之外,其它的也会有自己的初始化逻辑。下面我们以BeanNameUrlHandlerMapping这个Bean为例。

首先我们先来查找到BeanNameUrlHandlerMapping这个类,并且进入。

我们可以看到BeanNameUrlHandlerMapping继承于AbstractDetectingUrlHandlerMapping这个类,跟进AbstractDetectingUrlHandlerMapping这个类之后我们又可以看到AbstractDetectingUrlHandlerMapping又继承于AbstractUrlHandlerMapping这个类,再次跟进,这个类又继承于AbstractHandlerMapping,再次跟进,这个类又继承于WebApplicationObjectSupport,再次跟进,这个类又继承于ApplicationObjectSupport,再次跟进,这个类最后实现了ApplicationContextAware这个接口,下面这几张截图就是整体的继承和实现关系。

在ApplicationContextAware接口中有一个setApplicationContext()回调方法

相当于BeanNameUrlHandlerMapping这个Bean对象在创建的过程中间它会来调setApplicationContext()方法的具体的实现。而这个方法具体的实现是在ApplicationObjectSupport这个类里面,因为它们之间存在继承关系,所以我们来到ApplicationObjectSupport这个类中找到这个方法。

而在这个方法里面它会调用initApplicationContext()这个方法,我们继续跟进一下这个方法

从而继续调用里面的initApplicationContext()方法,继续跟进之后。

点击左侧的蓝色图标,找到具体的实现

再次点击左侧的蓝色图标

所以BeanNameUrlHandlerMapping这个Bean对象它在初始化的时候会调用initApplicationContext()方法来进行初始化。而我们可以看到这个方法中还有一个detectHandlers()方法,跟进之后我们可以简单看一下这段代码,首先拿到Spring容器,之后会拿到所有Object类型的Bean的名字,然后根据名字一个一个去遍历,然后就把每个Bean的名字给解析出来

跟进一下里面解析名字的方法determineUrlsForHandler()

点击左侧图标

这个方法里面要求说Bean的名字必须要以"/"开头 ,这里面并没有考虑类型之类的问题,它只关心名字必须以"/"开头,只要满足条件就会被筛选出来,我们再回到刚才的方法中。

满足条件的Bean会被当做是一个Handler,并且调用registerHandler()方法,跟进过去

点击for循环内的registerHandler()方法,跟进

来到这个方法之后往下拉

这些满足条件的Bean就会被注册到一个Map里面(handlerMap)

举个例子,下面这种的Controller就满足上面的条件,名字以"/"开头,但是现在它还不能去处理请求,这涉及到了adapter(后面再说)

java 复制代码
import org. springframework.stereotype.Component;
 
@Component("/test")
public class XXXBeanNameController {
 

}

它收到请求之后就根据这个"/test",找到了这个Bean,但是找到了这个Bean要实现什么方法呢,我们需要实现一个接口

java 复制代码
import org. springframework. web. servlet. ModelAndView;
import org. springframework. web. servlet. mvc. Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component("/ test")
public class XXXBeanNameController implements Controller {

   @Override
   public ModeLAndView handleRequest(HttpServletRequest request, HttpServletResponse 
   response) throws Exception{
       System. out. println(" test kanglingfeng");
       return null;
   }
}

这样我们就可以成功运行了。除了实现Controller接口之外,还可以实现HttpRequestHandler接口

java 复制代码
import org. springframework. web. servlet. ModelAndView;
import org. springframework. web. servlet. mvc. Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component("/ test")
public class XXXBeanNameController implements HttpRequestHandler{

   @Override
   public void handleRequest(HttpServletRequest request, HttpServletResponse 
   response) throws ServletException,IOException{
       System. out. println(" test kanglingfeng");
   }
}

我们来归纳一下这套流程

首先SpringMVC接收到一个请求之后(/test),根据这个test就能够找到对应的Bean对象,也就是能找到XXXBeanNameController 这个对象,找到这个对象之后,SpringMVC会把这个对象传进来,也就是下面代码中的supports(Object handler),传进来之后,判断这个类的类型是不是HttpRequestHandler接口,如果是,SpringMVC就会继续调用下面的handle方法

把它接收的请求传给这个handle方法,然后handle方法就会把这个Bean对象进行强制转换,然后直接调用XXXBeanNameController里面的handleRequest()方法,从而去处理请求。

相关推荐
yaoxin5211231 分钟前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python
做个文艺程序员18 分钟前
Linux第24篇:Java应用监控体系搭建:Prometheus+Grafana可视化运维
java·grafana·prometheus
FF2501_940228581 小时前
Grid 构建月历网格:7 列模板 + 日期占位算法
后端·华为·harmonyos·鸿蒙系统
神奇小汤圆1 小时前
线程池的 DiscardPolicy 为什么是「静默杀手」?一个生产事故的完整复盘
后端
大鸡腿同学1 小时前
个人博主 AI 剪辑实操:口播视频 3 步出片,省 80% 剪辑时间
后端
小钻风33661 小时前
Spring Boot 文件上传详解:深入理解 MultipartFile 的使用与原理
java·开发语言
其美杰布-富贵-李1 小时前
Spring Boot 工程开发全流程说明
java·spring boot·后端
xianjixiance_1 小时前
HarmonyOS应用开发实战:萌宠日记 - 整体架构设计与技术选型解析
后端
掘金者阿豪1 小时前
数据库优化器到底在想什么:一个SQL今天能跑明天崩的背后
后端
b130538100492 小时前
HarmonyOS应用开发实战:萌宠日记 - 回调函数模式
后端