找到Spring官网,找到MVC模块
https://spring.io/projects/spring-framework
image.png

SpringMVC框架搭建流程

开发过程,其实之前也写过了 https://www.yuque.com/jixiangkuaile/kk8w4w/ogy29f
1)新建maven项目,注意选择webapp骨架
2)引入依赖,并配置DispatcherServlet前端控制器
3)开发处理具体业务逻辑的Handler(@Controller、 @RequestMapping)
4)xml配置文件配置controller扫描,配置springmvc三件文
5)将xml文件路径告诉springmvc(DispatcherServlet)

1.1、新建maven项目,注意选择webapp骨架

image.png
image.png

1.2、创建成功但没有src等目录,那就自己创建

image.png
image.png

2.1、在整个项目的pom.xml文件中引入依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.slin.edu</groupId>
  6. <artifactId>slin-spring-mvc</artifactId>
  7. <version>1.0-SNAPSHOT</version>
  8. <packaging>war</packaging>
  9. <properties>
  10. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  11. <maven.compiler.source>11</maven.compiler.source>
  12. <maven.compiler.target>11</maven.compiler.target>
  13. </properties>
  14. <dependencies>
  15. <dependency>
  16. <groupId>junit</groupId>
  17. <artifactId>junit</artifactId>
  18. <version>4.11</version>
  19. <scope>test</scope>
  20. </dependency>
  21. <!--引入spring webmvc的依赖
  22. 因为springweb是spring的外部功能,
  23. 所以一定会依赖springcontext这些功能-->
  24. <dependency>
  25. <groupId>org.springframework</groupId>
  26. <artifactId>spring-webmvc</artifactId>
  27. <version>5.1.12.RELEASE</version>
  28. </dependency>
  29. </dependencies>
  30. <build>
  31. <plugins>
  32. <plugin>
  33. <!--要把tomcat的插件引入进来-->
  34. <groupId>org.apache.tomcat.maven</groupId>
  35. <artifactId>tomcat7-maven-plugin</artifactId>
  36. <version>2.2</version>
  37. <configuration>
  38. <port>8080</port><!--指定端口号-->
  39. <path>/</path><!--指定上下文-->
  40. </configuration>
  41. </plugin>
  42. </plugins>
  43. </build>
  44. </project>

2.2、配置DispatcherServlet前端控制器

这里整体可以称之为 springmvc相关配置,但是整个项目是通过Tomcat来启动的,实则是先配置Tomcat,
所有请求过来的连接都是经过Tomcat的。
先看一下官网对这个类的解析
image.png

web.xml配置寄存器和初始化的示例DispatcherServlet(从官网拷贝)
先要注意一点:
image.png

删除后的配置如下
image.png

2.3、可以先不用父容器,也能完整SpringMVC的工作

image.png
先看一下子容器的配置文件
image.png

3.1、开发处理具体业务逻辑的Handler(@RestController、 @GetMapping)

image.png

4.1、就是部署Tomcat并发布,测试

当然,也可以内置Tomcat
image.png
启动没有报错,但是访问出现如下情况
image.png

那么就需要将项目发布才可以,就得需要如下操作
image.png
image.png

再次启动测试
image.png

4.2、调用访问路径查看效果

image.png

对项目下面的配置文件进行分析

1、对应web.xml,spring.xml是什么东西,谁用的

image.png

2、对于请求流程的分析image.png

3、为什么配置Spring.xml在下面呢

image.png

整个过程是如何的呢?

A、首先是启动Tomcat
B、然后找到web.xml指定的DispatcherServlet去实例化
C、在Servlet规范中,任何一个Servlet都可以实现一个init()方法。当上面的DispatcherServlet实例化完后,就会去调用init() 方法。

在Tomcat启动后,所有的DispatcherServlet实例创建好之后,就会准守Servlet的规范,去调用DispatcherServlet.init() 方法。

1、先看Servlet规范中的init()方法

通过DispatcherServlet类一直找到其父类的父类,反正找到最顶的Servlet,并找到init()方法
image.png

2、debug 进去

image.png

3、初始化容器

image.png

4、那么进来看是如何初始化的

image.png

5、继续调用重载方法

image.png

6、开始看到去调用实例化类

image.png

7、调用无参构造从实例化

image.png

8、构造器进行实例化

image.png

image.png

然后就是一路返回到第6点

9、得到容器,给容器赋值

先看配置文件
image.png
image.png

再看如何赋值及启动

image.png
image.png

啥是父子容器呢

1、父子容器模型图

image.png

2、整个项目中如何配置父子容器呢

就得需要借助Tomcat的监听机制,来告诉它给单独创建一个父容器

image.png

有了这个监听机制,也就是说,除了要实现之前的东西外,还要调用监听类里面的对应方法,去创建容器

看源码如何通过监听机制去创建容器的呢?

1、

image.png

2、

image.png

3、debug进来

image.png

4、父容器得到创建了

image.png

image.png

5、当父容器创建完毕,再创建子容器,则传给子容器

image.png

=========Tomcat调用配置文件创建容器的过程=================
HttpServletBean#init
FrameworkServlet#initServletBean
FrameworkServlet#initWebApplicationContext
FrameworkServlet#createWebApplicationContext
FrameworkServlet#createWebApplicationContext
BeanUtils#instantiateClass

零配置底层原理分析

1、看官网介绍

image.png

2.1、如何实现零配置呢

先创建一个配置类
image.png

2.2、

image.png

2.3、如何实现父子容器呢

image.png

3、把web.xml都注掉,然后重新启动

image.png

4、疑问来了

image.png

4.1、就得看它是从哪里调进来的(查看调用栈)

image.png

4.2、通过Tomcat提供一个接口给开发者进行实现

image.png
里面的方法是这个
image.png

4.3、SpringServletContainerInitializer实现了上面的接口

然后通过SPI机制进行配置,然后Tomcat启动就会找到开发这所实现的那个类,调用onStartup方法

image.png

image.png

所以就调到自己写的onStartup() 方法

1、最主要的是先通过SPI机制找到要初始化的类
2、就找到初始化类的onStartup方法
3、再找到自定义的实现类的onStartup方法