这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战
Spring 环境预备
仅作为学习而言直接新建一个Springboot项目导入idea进行debug调试是最为方便的做法,但如果希望在学习的过程中对一些代码进行修改来验证自己的想法,最好还是在github上把 spring-projects/spring-framework fork到自己的仓库,然后clone到本地进行调试学习.
本文及后续文章中都会使用spring源码编译的方式进行学习,我的本机环境都会和当前时间节点spring-framework的main分支代码同步,确保是最新环境.
Debug 环境预备
在阅读源码之前我们得先让SpringMVC运行起来,这时候就得先准备一个Servlet容器了.
脱离Springboot使用SpringMVC给人的第一想法就是先去下载一个tomcat安装包,使用tomcat安装包这一套方案不是说不行,但未免太过繁琐,建议直接使用内嵌tomcat运行.
引入内嵌tomcat依赖
找到spring-webmvc项目中的spring-webmvc.gradle文件,引入内嵌tomcat依赖.
testImplementation("org.apache.tomcat.embed:tomcat-embed-core")
编写一个内嵌tomcat和SpringMVC整合的用例
下面会有一段使用内嵌tomcat和SpringMVC整合的用例,可以看出它跟使用web.xml的配置流程基本一样,只需要把这个class放到webmvc的源码目录或测试目录下能正常运行起来就算是把SpringMVC的源码学习环境搭建成功了.
package com.xay.app;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import java.io.File;
@RestController
public class TomcatTest {
@GetMapping("/ping")
public String ping() {
return "pong";
}
public static void main(String[] args) {
Tomcat tomcat = new Tomcat();
Connector conn = new Connector();
conn.setPort(80);
tomcat.setConnector(conn);
DispatcherServlet dispatcherServlet = new DispatcherServlet();
AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
annotationConfigWebApplicationContext.register(TomcatTest.class);
annotationConfigWebApplicationContext.refresh();
dispatcherServlet.setApplicationContext(annotationConfigWebApplicationContext);
Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
Tomcat.addServlet(ctx, "mvc", dispatcherServlet).addMapping("/*");
try {
tomcat.start();
tomcat.getServer().await();
} catch (LifecycleException e) {
e.printStackTrace();
}
}
}
结语
值得注意的是DispatcherServlet这个实例对象,他是桥接SpringContext和Tomcat的入口所在,学习springmvc主要就是学习springmvc的接口设计思想和DispatcherServlet的业务处理流程.后面我会继续分享自己学习springmvc源码的笔记.