文章目录
前言
作为java开发,经常使用SpringBoot框架,那么掌握SpringBoot的请求的全流程还是十分必要的。
没有研究源码之前,有一些疑问:
- 为什么要返回json串的时候需要在方法上加
@ResponseBody
,或者在类上加@RestController
- 为什么返回String类型,不加
@ResponseBody
,就是要去找视图解析器 - 返回modelAndVIew类型并加
@ResponseBody
,那返回的json串,还是页面呢 - 视图解析器可以有多个吗,如何选择的?加了
@ResponseBody
之后,还会经过视图解析器处理吗 - 为什么有时候使用了fastjson,最好也需要加fastjson的消息处理器HttpMessageConverters
- 若加上方法上加
@RequestMapping("/index.html")
,且resoure目录下的static目录也有一个index.html页面会怎么样
其实还有很多其他疑问,为什么会这样,其实很重要的一点就是,现在的开发推荐:约定大于配置,配置大于编码。
很多东西已经约定好的,直接告诉我们就这样子,按照这样写就对了,或者很多starter的使用,只要在yaml配置一下就可以了,对于编码的要求较少。那么因为框架或者工具等编码较少,我们就不知道这些框架本来的逻辑。有疑问就很自然了。
一、SpringBoot源码
SpringBoot源码分析是十分必要的,包括但不限于
- 包括启动类上的注解
@SpringBootApplication
就是一个很重要的知识点 - 另外main方法的运行之后,源码里
new SpringApplication(primarySources).run(args);
,这里有2个很重要的操作,分别是new和run,分析里面的源码可以看到spring.factories文件里自动配置类加载,各种解析器,拦截器,bean的定义,加载和创建等操作。 - 还有就是一个前端的get/post请求到controller方法经历了什么。
这次我就先分析第三个,看看一次请求经历了什么。
另外一篇文字是基本分析,有兴趣可以看看SpringMVC源码——doDispatch方法源码分析
二、代码准备
1、请求
下面以返回json格式为例
get请求入参
http://localhost:8080/spring/dataBinder?age=1&name=demoData
返回参数
{
“age”: 1,
“name”: “demoData”
}
2、controller层
@Controller
@RequestMapping("/spring")
@Slf4j
public class SpringController {
@GetMapping("/dataBinder")
@ApiOperation(value = "我是一个可爱的测试获取dataBinder的接口")
@ResponseBody
public DataBinder dataBinder(DataBinder dataBinder) {
return dataBinder;
}
}
@Data
class DataBinder {
String name;
Integer age;
}
3、分析起点
分析开始点org.springframework.web.servlet.DispatcherServlet#doDispatch
该方法protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception
是请求的必经之路。因为DispatcherServlet本身就一个servlet,它配置的匹配映射地址是 / 。在springboot中它是默认配置好了,在springmvc中,我们可以在web.xml文件中看到它的配置如下: