何时使用AbstractAnnotationConfigDispatcherServletInitializer和WebApplicationInitializer?

56
我正在使用Spring 4.0.7。我研究了如何通过JavaConfig配置Spring MVC。实际上,直到昨天,我看到了两种使用以下两个选项的配置: 1. 扩展AbstractAnnotationConfigDispatcherServletInitializer。 2. 扩展WebMvcConfigurerAdapter并实现WebApplicationInitializer。 注意:(2)是两个类,一个用于扩展,另一个用于实现。 我使用(2),因为我发现很多例子可以在其中配置转换器、格式化程序和资源处理程序等内容。 但是最近几天,我试图在StackOverflow上回答一个问题时,我发现了(1)存在。我在Google上概述了一下(1),也有一些使用(1)的例子。 我的问题就是如题所述。 谢谢。

将部署配置与上下文配置分离。 - Sotirios Delimanolis
2个回答

71

在Servlet 3.0规范发布后,几乎可以不使用xml配置Servlet容器。为此,Servlet规范中提供了ServletContainerInitializer。在这个类中,您可以像在web.xml中传统地注册过滤器、监听器、Servlet等。

Spring提供了一个实现SpringServletContainerInitializer的工具,它知道如何处理WebApplicationInitializer类。Spring还提供了一些基础类以便扩展从而让您的生活更轻松。AbstractAnnotationConfigDispatcherServletInitializer就是其中之一,它会注册一个ContextLoaderlistener(可选)和一个DispatcherServlet,并允许您轻松添加要加载到这两个类中的配置类,并对DispatcherServlet应用过滤器,并提供Servlet映射。

WebMvcConfigurerAdapter用于配置Spring MVC,替换被DispatcherServlet加载的XML文件来配置Spring MVC。应该使用@Configuration类来使用WebMvcConfigurerAdapter

@Configuration
@EnableWebMvc
public class WebConfiguration 
    extends WebMvcConfigurerAdapter implements WebApplicationInitializer
{ ... }

我不建议混合使用它们,因为它们基本上是两个不同的关注点。第一个是用于配置Servlet容器,而后者用于配置Spring MVC。

你会想把它们分成两个类。

用于配置目的。

@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter { ... }

用于引导应用程序的启动过程。

public class MyWebApplicationInitializer
    extends AbstractAnnotationConfigDispatcherServletInitializer
{

    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {RootConfig.class};
    }
    
    protected Class<?>[] getServletConfigClasses()  {
        return new Class[] {WebConfiguration .class};
    }
    
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }

}

另一个优点是,现在您可以使用Spring提供的便捷类,而不是手动配置 DispatcherServlet 和/或 ContextLoaderListener 。


是的,混合(1)和(2)不明智,目前我正在使用(2),因此(extends WebMvcConfigurerAdapter and implements WebApplicationInitializer)。 - Manuel Jordan
我有些困惑,我看到了一些关于使用WebMvcConfigurerAdapter和WebApplicationInitializer的例子,我只使用这两个“对象”,一个用来替换web.xml,另一个用来配置Spring MVC。 - Manuel Jordan
你使用哪些类?谢谢。 - Manuel Jordan
我遇到了一个关于Abstract...ServletInitializer的奇怪问题。如果有人能帮忙,请在这里发布 - http://stackoverflow.com/questions/37498024/nosuchbeandefinitionexception-no-qualifying-bean-of-type-repository-found-for - Shamseer
1
我在哪里可以获取RootConfig.class文件? - zygimantus
显示剩余4条评论

23

要从头开始,值得研究一下servlet容器的启动方式。

因此要开始,SpringServletContainerInitializer必须找到正确的实现了 WebApplicationInitializer的类。实现方法有两种:

  1. 一种是独立实现 WebApplicationInitializer;该接口在Spring 3.1中引入。
  2. 第二种是扩展 AbstractAnnotationConfigDispatcherServletInitializer类,该类也实现了 WebApplicationInitializer。该类在Spring 3.2中引入,是“使用基于Java的Spring配置的应用程序的首选方法”-请参见链接。它可以启动servlet应用程序上下文以及根应用程序上下文。
我还想强调一下,您提到的WebMvcConfigurerAdapter不应与WebApplicationInitializer混淆。正如其名称所示 - 它与配置“Mvc”有关。它是一个适配器类,实现了WebMvcConfigurer中的空方法。当您使用@EnableWebMvc注释配置Mvc控制器时,可以使用它。

希望这能帮到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接