重复调用WebApplicationInitializer

时间:2012-10-09 20:38:55

标签: spring tomcat spring-mvc

我有一个基于Spring 3.1的应用程序,托管在Tomcat 7.x(最新版本)下。该应用程序仅使用Java配置(无web.xml,无Spring XML配置)。所有单元测试都在通过,包括使用Spring Java配置(@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]

3 个答案:

答案 0 :(得分:0)

这里的问题是Maven Overlay将一个Spring xml配置文件中的 crap 转储到我的应用程序中。无论出于何种原因,这导致WebApplicationInitializer.onStartup()被调用两次。可能是应用程序上下文和servlet上下文的初始化。从叠加层中删除,应用程序正在按预期初始化。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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