SpringMVC源码学习环境搭建

498 阅读2分钟

这是我参与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")

image.png

编写一个内嵌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源码的笔记.