Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 基于Spring代码的配置-IllegalArgumentException:需要ServletContext_Java_Spring_Tomcat_Configuration - Fatal编程技术网

Java 基于Spring代码的配置-IllegalArgumentException:需要ServletContext

Java 基于Spring代码的配置-IllegalArgumentException:需要ServletContext,java,spring,tomcat,configuration,Java,Spring,Tomcat,Configuration,我在这里找到了一个100%基于代码的spring配置示例: http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html 内容: public class MyWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(Ser

我在这里找到了一个100%基于代码的spring配置示例:

http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html
内容:

public class MyWebAppInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext container) {
  // Create the 'root' Spring application context
  AnnotationConfigWebApplicationContext rootContext =
    new AnnotationConfigWebApplicationContext();
  rootContext.register(AppConfig.class);

  // Manage the lifecycle of the root application context
  container.addListener(new ContextLoaderListener(rootContext));

  // Create the dispatcher servlet's Spring application context
  AnnotationConfigWebApplicationContext dispatcherContext =
    new AnnotationConfigWebApplicationContext();
  dispatcherContext.register(DispatcherConfig.class);

  // Register and map the dispatcher servlet
  ServletRegistration.Dynamic dispatcher =
    container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
  dispatcher.setLoadOnStartup(1);
  dispatcher.addMapping("/");
}

}
在上面的示例中,他们在注册配置类后从未调用过refresh()。 但是API说,必须调用refresh(),上下文才能完全处理新类。 所以我在每个register语句后面添加了refresh()

rootContext.register(AppConfig.class);
rootContext.refresh();

dispatcherContext.register(DispatcherConfig.class);
dispatcherContext.refresh();
因此:

SEVERE: ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: Failed to start component    [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:702)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:699)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1647)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:465)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:415)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1487)
at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:97)
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1328)
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1420)
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:848)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
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)
    Caused by: 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:592)
但是如果我删除refresh()(显然)它工作得很好(我使用Tomcat8.0)
最后,我不完全理解在这样的代码中是否必须使用refresh()。如果没有-我应该在什么时候使用它?

在您的情况下,这只对传递给
DispatcherServlet的
应用程序上下文
重要。
DispatcherServlet
构造函数声明

给定的web应用程序上下文可能会刷新,也可能尚未刷新。如果 它尚未刷新(推荐的方法),然后 将发生以下情况:

  • 如果给定上下文没有父上下文,则根应用程序上下文将设置为父上下文
  • 如果给定的上下文尚未分配id,则将为其分配一个id
  • ServletContext
    ServletConfig
    对象将委托给应用程序上下文
  • 将调用后处理WebApplicationContext
  • 通过指定的任何
    ApplicationContextInitializers
    “contextInitializerClasses”初始化参数或通过 将应用setContextInitializers属性
  • 如果上下文实现了
    ConfigurableApplicationContext
  • 如果已刷新上下文,则不会执行上述操作 假设用户已执行这些操作,则发生 (或不)根据他们的具体需要。

    因此,对于
    DispatcherServlet
    ,您必须执行以下操作

    AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
    dispatcherContext.register(DispatcherConfig.class);
    
    // will take care of calling refresh() on the ApplicationContext
    ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
    
    这对于
    DispatcherServlet
    配置是必需的,因为由于
    @EnableWebMvc
    (或等效的
    )生成的一些bean需要Servlet容器提供的
    ServletContext
    和/或
    ServletConfig
    对象

    根上下文不应该有这样的依赖关系,这样做是安全的

    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    rootContext.register(AppConfig.class);
    rootContext.refresh();
    

    请注意,您可以通过将
    @Configuration
    类作为参数传递给构造函数来创建
    注释ConfigWebApplicationContext
    对象。

    请发布堆栈跟踪的其余部分。