关于Spring Mvc的配置

 

传统的配置(Servlet2.0)

传统的Spring Mvc配置时须要在web.xml上配置以下内容:

Spring MVC应用篇---启动配置那些事

这其实是Servlet2.0的规范:

1.配置一个ContextLoaderListener作为spring容器初始化的监听器,这样web容器启动的时候(比如tomcat)会通过这个监听器初始化容器。

2.配置spring容器初始化时须要读取的配置文件,配合ContextLoaderListener使用。

3.配置一个DispatcherServlet,请求会经过这个Servlet,这是Spring Mvc的核心。

4.须要的话配置一个web mvc相关的配置文件,比如请求映射器;视图解析器;消息转换器等,这里和上面Spring容器的配置文件区分开来。

5.DispatcherServlet有个onRefresh方法须要初始化各种组件,底层是实现了Servlet的init接口,这里设为1的话,在项目启动的时候就会执行让DispatcherServlet初始化各种组件。如果不这么设的话,初始化会延迟到首次请求进来时,所以第一次请求的时候响应会比较慢。所以官方也建议设置为1。

6.配置DispatcherServlet的路径映射。

 

官网推荐配置(Servlet3.0&Tomcat8)

事实上,Spring官网现在已经推荐另外一种配置方式:

Spring MVC应用篇---启动配置那些事

只需要实现WebApplicationInitializer接口,可以看到官网给出的demo中的相关配置其实已经可以完全取代传统的web.xml了,且这种形式我们可以通过Java-Config加注解的形式来配置我们的项目,做到了“零xml”。

 

Servlet3.0新规范

那么Spring是如何做到的呢?这里就要讲到Servlet了,Servlet从3.0开始定义了一种新的规范,其定义了一个ServletContainerInitializer接口:

Spring MVC应用篇---启动配置那些事

白话说一下这个新规范:

1.我们只要自定义一个类,实现ServletContainerInitializer这个接口,重写其中的onStartup方法,然后在项目的META-INF/services目录下创建一个名字叫作javax.servlet.ServletContainerInitializer的文件,文件内容是上一步自定义类在项目中的路径。然后当web容器启动的时候就会自动去调用这个自定义类的onStartup方法。

2.只要在这个自定义类上加上HandlesTypes注解,然后指定一个Class类,那么项目中所有这个Class类的对象都会在onStartup方法执行时被赋到这个方法的第一个参数中。第二个参数是Servlet上下文对象。

Spring MVC应用篇---启动配置那些事

 

Spring MVC对Servlet3.0的实现

知道了Servlet3.0的新规范之后,我们来看下Spring MVC是怎么实现这个规范的。

spring-web模块中配置了一个javax.servlet.ServletContainerInitializer文件:

Spring MVC应用篇---启动配置那些事

javax.servlet.ServletContainerInitializer文件中指定了Spring自己的这个类:

Spring MVC应用篇---启动配置那些事

看下这个SpringServletContainerInitializer类:

Spring MVC应用篇---启动配置那些事

可以看到SpringServletContainerInitializer就实现了Servlet3.0的规范!@HandlesTypes注解中指定的就是WebApplicationInitializer类,看下SpringServletContainerInitializer实现的onStartup方法:

Spring MVC应用篇---启动配置那些事

所以回到最前面,只需要自定义个类实现WebApplicationInitializer接口,重写onStartup,那么web容器启动的时候,就会调用,Spring MVC官网就是在这个方法里进行了spring容器和DispatcherServlet的初始化工作。

 

Spring Boot是怎么做到的?

Spring Boot有两种启动方法:

第一种:jar包方式,直接在main函数中调用SpringApplication#run方法,内部其实是内建了一个tomcat,另外初始化了spring容器和DispatcherServlet,这里的DispatcherServlet也是通过一个TomcatStarter的类,最终来实例化出来的,TomcatStarter就是继承了ServletContainerInitializer。

这里不细讲,在后面分析Boot源码时再研究。

第二种:war包方式,war包是外置的tomcat。如果要使用这种方式,就要继承SpringBootServletInitializer这个类,可以看到SpringBootServletInitializer就是实现了WebApplicationInitializer这个接口。

Spring MVC应用篇---启动配置那些事

分类:

技术点:

相关文章: