Spring 重复调用WebApplicationInitializer

Spring 重复调用WebApplicationInitializer,spring,tomcat,spring-mvc,Spring,Tomcat,Spring Mvc,我有一个基于Spring3.1的应用程序,托管在Tomcat7.x(最新版本)下。该应用程序是专门用Java配置的(没有web.xml,没有SpringXML配置)。所有单元测试都通过了,包括使用SpringJava配置的单元测试(@ContextConfiguration) 问题在于,部署应用程序时,WebApplicationInitializer实现会被多次调用。过滤器和侦听器的重复注册会导致异常,并且应用程序永远不会启动 我不希望重复调用WebApplicationInitializer

我有一个基于Spring3.1的应用程序,托管在Tomcat7.x(最新版本)下。该应用程序是专门用Java配置的(没有
web.xml
,没有SpringXML配置)。所有单元测试都通过了,包括使用SpringJava配置的单元测试(
@ContextConfiguration

问题在于,部署应用程序时,WebApplicationInitializer实现会被多次调用。过滤器和侦听器的重复注册会导致异常,并且应用程序永远不会启动

我不希望重复调用
WebApplicationInitializer.onStartup()
,如果可能,我希望消除这种行为。如果有人对为什么会发生这种情况,以及如何阻止它提出建议,我将非常感激

更新我相信问题出在初始化类本身之外,但这里是为了防止我弄错

public class DeploymentDescriptor implements WebApplicationInitializer {

    private static final Logger LOGGER = LoggerFactory.getLogger("org.ghc.web-app-initializer");

    @Override
    public void onStartup (ServletContext servletContext) throws ServletException {
        // This is the programmatic way of declaring filters. This allows you to order
        // Filters. The order of these security filters DOES MATTER!
        FilterRegistration.Dynamic mockSecurityFilter       = servletContext.addFilter ("mockSecurityFilter", "org.ghc.security.MockSecurityFilter");
        mockSecurityFilter.addMappingForUrlPatterns         (EnumSet.of (REQUEST), true, "/*");

        FilterRegistration.Dynamic siteMinderSecurityFilter = servletContext.addFilter ("siteMinderSecurityFilter", "org.ghc.security.SiteMinderSecurityFilter");
        siteMinderSecurityFilter.addMappingForUrlPatterns   (EnumSet.of (REQUEST), true, "/*");

        FilterRegistration.Dynamic userDetailsStoreFilter   = servletContext.addFilter ("userDetailsStoreFilter", "org.ghc.security.UserDetailsStoreFilter");
        userDetailsStoreFilter.addMappingForUrlPatterns     (EnumSet.of (REQUEST), true, "/*");


        // Static resource handling using "default" servlet
        servletContext.getServletRegistration ("default").addMapping ("*.js", "*.css", "*.jpg", "*.gif", "*.png");
        // Map jspf files to jsp servlet
        servletContext.getServletRegistration ("jsp").addMapping ("*.jspf");


        // Spin up the Spring 3.1 class that can scan a package tree for classes
        // annotated with @Configuration. See org.ghc.spring3.ControllerConfiguration for
        // this example.
        final AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext ();
        dispatcherContext.setServletContext (servletContext);
        dispatcherContext.register(ScProviderDirectory.class);
        dispatcherContext.refresh ();

        // Spin up the Spring DispatcherServlet (just like before) passing the just built
        // application context. Load it like the regular Servlet that it is!
        final ServletRegistration.Dynamic servlet = servletContext.addServlet ("spring", new DispatcherServlet(dispatcherContext));
        servlet.setLoadOnStartup (1);
        servlet.addMapping ("/");  // Make sure this is NOT "/*"!
    }
}
更新2这太奇怪了。Tomcat日志似乎标识了DeploymentDescriptor类的两个实例。不过,我验证了在我的.war文件中只有一个此类的实例。我不知道第二个(幻影)实例是从哪里来的,但至少这解释了为什么类被扫描两次

logs/localhost.2012-10-09.log:INFO: Spring WebApplicationInitializers detected on classpath: [org.ghc.configuration.DeploymentDescriptor@3b29642c]
logs/localhost.2012-10-09.log:INFO: Spring WebApplicationInitializers detected on classpath: [org.ghc.configuration.DeploymentDescriptor@432c4c7a]

这里的问题是Maven重叠将SpringXML配置文件转储到我的应用程序中。无论出于何种原因,这都会导致调用两次
WebApplicationInitializer.onStartup()
。可能是应用程序上下文和servlet上下文的初始化。关闭覆盖,应用程序正在按预期初始化。

这里的问题是Maven覆盖将Spring xml配置文件转储到我的应用程序中。无论出于何种原因,这都会导致调用两次
WebApplicationInitializer.onStartup()
。可能是应用程序上下文和servlet上下文的初始化。关闭覆盖,应用程序正在按预期初始化。

我也遇到了同样的问题。问题是我有多个像Biju K.建议的spring web*.jar(一个作为战争的一部分,另一个在共享的/tomcat库中)。

我也有同样的问题。问题是我有多个像Biju K.建议的spring web*.jar(一个作为战争的一部分,另一个在共享的/tomcat库中)。

我也有同样的问题。在web应用程序模块的目录中运行
mvn clean
,然后启动Tomcat为我解决了这个问题。

我也遇到了同样的问题。在web应用程序模块的目录中运行
mvn clean
,然后启动Tomcat为我解决了这个问题。

有趣的是,想知道初始化程序是否引发了一些异常,您能否添加更多日志以确保我一直在使用调试器观看(Java配置的真正好处)。第一次一切顺利。第二个生成一个NPE(servletContext.addFilter()返回null,然后对该筛选器的调用导致NPE)。对ServletContext的其他调用在第一次调用后也会出现问题。我认为它更像是注册被检测到的WebApplicationInitializers的
SpringServletContainerInitializer
的两个实例。可能有多个spring web*.jar在某处?很好地验证了我的依赖关系。不幸的是,它们是干净的,没有版本不匹配,没有冲突。如果在日志条目上向右滚动,它似乎实际上是在两次查找我的DeploymentDescriptor类(
DeploymentDescriptor
@3b29642c和
DeploymentDescriptor
@432c4c7a),而不是另一个
WebApplicationInitializers
实现。我有几个这样的应用程序,我不能简单地找出为什么这一个表现不同。再次感谢你的想法!有趣的是,想知道是否从初始化器中抛出了一些异常,您是否可以添加更多日志以确保我一直在使用调试器进行监视(Java配置的真正好处)。第一次一切顺利。第二个生成一个NPE(servletContext.addFilter()返回null,然后对该筛选器的调用导致NPE)。对ServletContext的其他调用在第一次调用后也会出现问题。我认为它更像是注册被检测到的WebApplicationInitializers的
SpringServletContainerInitializer
的两个实例。可能有多个spring web*.jar在某处?很好地验证了我的依赖关系。不幸的是,它们是干净的,没有版本不匹配,没有冲突。如果在日志条目上向右滚动,它似乎实际上是在两次查找我的DeploymentDescriptor类(
DeploymentDescriptor
@3b29642c和
DeploymentDescriptor
@432c4c7a),而不是另一个
WebApplicationInitializers
实现。我有几个这样的应用程序,我不能简单地找出为什么这一个表现不同。再次感谢你的想法!我也有同样的问题,你到底是怎么“杀死Maven”的?你能再解释一下吗?我正在研究,但我不确定如何做到这一点?已经有一段时间了,但我相信问题的核心是(有意)使用基于Java的Spring配置类,以及存在XML Spring配置文件(无意)。我不记得xml是上下文范围还是servlet范围。删除意外包含(在我的例子中覆盖)的xml配置文件为我清除了它。对不起,我不记得细节了…我也有同样的问题,你到底是怎么“杀死Maven Overlay”的?你能再解释一下吗?我正在研究,但我不确定如何做到这一点?已经有一段时间了,但我相信问题的核心是(有意)使用基于Java的Spring配置类,以及存在XML Spring配置文件(无意)。我不记得xml是上下文范围还是servlet范围。删除我的ca中意外包含(覆盖)的