Spring JavaConfig配置异常:需要ServletContext来配置默认的servlet处理

时间:2014-09-16 21:15:11

标签: java spring tomcat configuration spring-java-config

我试图用纯Spring 4.1.0 JavaConfig设置替换我的web.xml。根据我读过的示例和API文档,后面的“应该”工作:

public class WebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        // Create the root appcontext (replaces the web.xml context-param & ContextLoaderListener)
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(RootConfig.class);
        // since we registered RootConfig instead of passing it to the constructor
        rootContext.refresh(); 
    ...
    ...
}

}

使用RootConfig.java:

@Configuration
@ComponentScan(basePackages="com.ia", excludeFilters=@ComponentScan.Filter(type=FilterType.ANNOTATION, value=Controller.class))
@EnableSpringConfigured
public class RootConfig{
}

但是,这样做时,我收到以下错误消息:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.web.servlet.HandlerMapping org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping()] threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:601)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1113)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1008)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:505)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at com.ia.system.configuration.WebAppInitializer.onStartup(WebAppInitializer.java:60)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5423)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)

违规行位于:

rootContext.refresh();

如果我删除rootContext.refresh()语句,一切似乎都能正常工作。

这与this SO Post中指定的错误相同,但是接受的响应似乎表明refresh()应该适用于rootContext。对我来说情况并非如此。我不确定为什么这会引起错误。

我已经在几个地方读过你可以将@Configuration类传递给构造函数而不是调用refresh()方法,但我不确定是哪个构造函数。 AnnotationConfigWebApplicationContext()没有这样的构造函数,所以我有点困惑。

1 个答案:

答案 0 :(得分:5)

在调用refresh()之前尝试设置servlet上下文:

rootContext.setServletContext(servletContext);