Servlet 3.0 新特性
Servlet 3.0 文档下载:https://jcp.org/aboutJava/communityprocess/mrel/jsr315/index.html
Servlet 3.0 新特性:Shared library(共享库) / runtimes pluggability (运行时插件能力)
- Servlet 容器启动时会扫描当前应用每个 jar 包里面的 ServletContainerInitializer 的实现
- 在应用路径下创建一个 META-INF/services/javax.servlet.ServletContainerInitializer 文件,文件中存放 ServletContainerInitializer 实现类全限定类名
即容器在启动时,会扫描当前应用每一个jar包里面 META-INF/services/javax.servlet.ServletContainerInitializer 指定的实现类(全限定路径名),启动并运行这个实现类的方法
在容器启动时支持使用 @HandlerType() 自动扫描感兴趣的类,并将加载其子类和实现类(不包括本身),存放到 Set
@HandlesTypes(value = {感兴趣的类型})
public class MyServletContainerInitializer implements ServletContainerInitializer {
/**
* @param c Set集合,即上述@HandlesTypes注解扫描进来的类集合
* @param ctx servletContext,容器上下文
* @throws ServletException
*/
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
}
}
SpringServletContainerInitializer
SpringServletContainerInitializer:由 spring-web 提供,使用 servlet3.0 基于 spi 的插件能力,能够在容器启动时被 servlet 容器启动并加载
SpringServletContainerInitializer :在容器启动的时候加载 WebApplicationInitializer 接口的实现类并运行实现类中的 onStartup() 方法
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
// ....
}
因此:
- 在引入 spring-web 的情况下可以使用 WebApplicationInitializer 的实现类来加载相应的 servlet、filter 和 listener
WebApplicationInitializer 接口
官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-container-config
WebApplicationInitializer 接口在 spring-webmvc 包中做了相关抽象实现,用来加载 Spring 容器:
- AbstractContextLoaderInitializer:用来创建根容器,createRootApplicationContext()
- AbstractDispatcherServletInitializer:
- 创建一个 web 的 ioc 容器:createServletApplicationContext()
- 创建 dispatcherServlet:createDispatcherServlet()
- 将创建的 DispatcherServlet 添加到 ServletContext 中:getServletMappings()
- AbstractAnnotationConfigDispatcherServletInitializer:注解方式配置的 DispatcherServlet 初始化器
- 创建根容器:createRootApplicationContext()
- 传入一个配置类:getRootConfigClasses()
- 创建 web 的 ioc 容器:createServletApplicationContext()
- 获取配置类:getServletConfigClasses()
简单来说,以注解方式来启动 SpringMVC,只需要继承 AbstractAnnotationConfigDispatcherServletInitializer 抽象类,实现抽象方法指定 DispatcherServlet 的配置信息:
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
// 创建 Spring 父容器配置
return new Class[]{ApplicationConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
// 创建 SpringMVC 容器配置
return new Class[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
// DispatcherServlet 的映射路径
return new String[]{"/"};
}
}