标签:数据 基于 Servle root 框架 基本 dma [] ted
在学习 Spring MVC 的过程中发现,Spring MVC 使用了不少 Servlet 3.0 的新特性,但鉴于我学习 Servlet 使用的教程是 《Head First Servlet & JSP》,其中的 Servlet 版本只有 2.5,因此不得不去研究一下 Servlet 3.0 的新特性在继续 Spring MVC 的学习。
这篇博客的主要内容便是在学习了 Servlet 3.0 的一些新特性之后对 Spring MVC 的启动配置过程的理解。
注意:博客的主要内容不是关于 Servlet 3.0 的新特性和 Spring MVC 的使用的。
首先我们来看一下一个基于 Java 的配置,其实就是《Spring 实战》第五章的那个配置:
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import spittr.web.WebConfig;
public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
这个配置的作用为:
/
, 也就是说所有的请求都会经由 DispatcherServlet 进行处理由于在看 《Head First Servlet & JSP》的时候配置都是基于 XML 的,因此在看到《Spring 实战》的这一部分的时候我产生了不少的疑惑,其中包括:
这里面的一些问题可以通过看书解决,但有一些问题,还是需要查阅网上的资料才行。
Servlet 3.0 中的新特性还是不少的,其中一个新特性便是:
Spring MVC 中的 ServletContainerInitializer 实现便是 SpringServletContainerInitializer,它的部分源码如下:
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {
// ...
}
}
onStartup 中的代码可以不用管,关键在于 SpringServletContainerInitializer 头上的那个注解:
@HandlesTypes(WebApplicationInitializer.class)
这个注解的意思是:初始化 SpringServletContainerInitializer 时扫描所有实现了 WebApplicationInitializer 接口的类,并作为参数 webAppInitializerClasses 传递给 onStartup 方法。
而我们在前面的配置中继承的 AbstractAnnotationConfigDispatcherServletInitializer 便是 WebApplicationInitializer 的一个便利的基础实现。
也就是说,Servlet 容器启动的时候会将我们的配置类发送给 SpringServletContainerInitializer 方法,然后在进行一系列的操作后完成 DispatcherServlet 的配置。
到了这里,大概能解决 Servlet 容器是怎么找到我们的配置类的,但还有一个问题是:Spring MVC 是怎么配置的 DispatcherServlet。
Servlet 3.0 中的一个新特性便是支持动态配置,我们可以通过 ServletContext 获取 Registration 对象进行动态配置,比如:
ServletRegistration.Dynamic registratio = ServletContext.addServlet("appServlet", DispatcherServlet.class);
registratio.addMapping("/");
我们可以看到,SpringServletContainerInitializer 的 onStartup 是可以获得 ServletContext 的,因此,我们完全可以在 onStartup 内部完成 DispatcherServlet 的配置。
很好,Servlet 容器是怎么配置 DispatcherServlet 的问题大概可以解决了。
通过查阅资料可以发现,DispatcherServlet 是 Spring MVC 框架自带的 Servlet,而 ContextLoaderListener 是 Spring MVC 自带的 ServletContextListener,不是新品种的监听者。
这两个类的源码链接如下:
在最开始的配置中,我们分别制定了 DispatcherServlet 和 ContextLoaderListener 中的应用上下文的配置类,这意味着:
翻书可以得知,这两个应用上下文的作用分别为:
这样一来,我们便可以大致总结一下配置 DispatcherServlet 和 ContextLoaderListener 中需要配置的内容了:
现在可以大致总结一下 Spring MVC 的配置过程了:
当然了,没有看源码的话,还有一个细节是不清楚的:
当然了,这无伤大雅 ( ̄▽ ̄)
本来还说贴一下 XML 的配置代码,结果《Spring 实战》提供的样例代码中直接把 web.xml 给去了,所以……
1 书上这里说的是:如果能发现的话,就会用实现类来配置 Servlet 容器。感觉这种说法挺不准确的,不知道是不是翻译的锅。
Java EE - Servlet 3.0 和 Spring MVC
标签:数据 基于 Servle root 框架 基本 dma [] ted
原文地址:https://www.cnblogs.com/rgbit/p/10806594.html