7.1.2 添加其他的 Servlet 和 Filter

按照 AbstractAnnotationConfigDispatcherServletInitializer 的定义,它会创建 DispatcherServlet 和 ContextLoaderListener。但是,如果你想注册其他的 Servlet、 Filter 或 Listener 的话,那该怎么办呢?

基于 Java 的初始化器(initializer)的一个好处就在于我们可以定义任意数量的初始化器类。因此,如果我们想往 Web 容器中注册其他组件的话,只需创建一个新的初始化器就可以了。最简单的方式就是实现 Spring 的 WebApplicationInitializer 接口。

例如,如下的程序清单展现了如何创建 WebApplicationInitializer 实现并注册一个 Servlet。

程序清单 7.1 通过实现 WebApplicationInitializer 来注册 Servlet
package com.myapp.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import com.myapp.MyServlet;

public class MyServletInitializer extends WebApplicationInitializer {
  
  @Override
  public void onStartup(ServletContext servletContext) throws ServletException {
    Dynamic myServlet = servlectContext.addServlet("myServlet", MyServlet.class);
    
    myServlect.addMapping("/custom/**");
  }

}

程序清单 7.1 是相当基础的 Servlet 注册初始化器类。它注册了一个 Servlet 并将其映射到一个路径上。我们也可以通过这种方式来手动注册 Dispatcher-Servlet。(但这并没有必要,因为AbstractAnnotationConfigDispatcher-ServletInitializer 没用太多代码就将这项任务完成得很漂亮。)

类似地,我们还可以创建新的 WebApplicationInitializer 实现来注册 Listener 和 Filter。例如,如下的程序清单展现了如何注册 Filter。

@Override
public void onStartup(ServlectContext servletContext) throws ServletException {

  javax.servlet.FilterRegistration.Dynamic filter = servletContext.addFilter("myFilter", MyFilter.class);
  
  filter.addMappingForUrlPatterns(null, false, "/custom/**");
} 

如果要将应用部署到支持 Servlet 3.0 的容器中,那么 WebApplicationInitializer 提供了一种通用的方式,实现在 Java 中注册 Servlet、Filter 和 Listener。不过,如果你只是注册 Filter, 并且该 Filter 只会映射到 DispatcherServlet 上的话,那么在 AbstractAnnotationConfigDispatcherServletInitializer 中还有一种快捷方式。

为了注册 Filter 并将其映射到 DispatcherServlet,所需要做的仅仅是重载 AbstractAnnotationConfigDispatcherServletInitializer 的 getServletFilters() 方法。例如,在如下的代码中,重载了 AbstractAnnotationConfigDispatcher-ServletInitializer 的 getServletFilters() 方法以注册 Filter:

@Override
protected Filter() getServletFilters() {
  return new Filter[] { new MyFilter() };
}

我们可以看到,这个方法返回的是一个 javax.servlet.Filter 的数组。在这里它只返回了一个 Filter,但它实际上可以返回任意数量的 Filter。在这里没有必要声明它的映射路径,getServletFilters() 方法返回的所有 Filter 都会映射到 DispatcherServlet 上。

如果要将应用部署到 Servlet 3.0 容器中,那么 Spring 提供了多种方式来注册 Servlet(包括 DispatcherServlet)、Filter 和 Listener,而不必创建 web.xml 文件。但是,如果你不想采取以上所述方案的话,也是可以的。假设你需要将应用部署到不支持 Servlet 3.0 的容器中(或者你只是希望使用 web.xml 文件),那么我们完全可以按照传统的方式,通过 web.xml 配置 Spring MVC。让我们看一下该怎么做。

Last updated