Spring 出现No WebApplicationContext found解决方法

web.xml缺少了Spring监听器:

<listener>  
  <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>  
listener>  
<context-param>  
  <param-name>contextConfigLocationparam-name>  
  <param-value>classpath:beans.xmlparam-value>  
context-param> 

这里就有个疑问了,为什么之前项目不加这一段运行正常。
经过研究后发现是新项目加载了Spring Session过滤器

 <filter>
        <filter-name>springSessionRepositoryFilterfilter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxyfilter-class>
    filter>

    <filter-mapping>
        <filter-name>springSessionRepositoryFilterfilter-name>
        <url-pattern>/*url-pattern>
        <dispatcher>REQUESTdispatcher>
        <dispatcher>ERRORdispatcher>
    filter-mapping>

该过滤器的功能需要依赖ContextLoaderListener所加载的beans.xml文件生成的applicationContext即Spring的上下文,而之前DispatcherServlet所加载的beans.xml文件生成的applicationContext为Spring mvc的上下文,shiro过滤器无法加载,所以得依靠监听器加载public的applicationContext。
附三个context的关系:

  • 对于一个web应用,web容器加载一个全局context供其使用,这个context就是servletContext,为其后续的spring IoC容器提供依赖。

  • 在web.xml中提供的ContextLoaderListener监听器,web容器启动时会触发容器初始化事件,ContextLoaderListener会监听这个事件,初始化一个根上下文即WebApplicationContext,实现类为XmlWebApplicationContext。这个就是Spring的IoC容器,spring将其以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为key存储在servletContext中

  • DispatcherServlet在初始化会建立自己的IoC容器用以持有Spring mvc相关的bean,它在建立的时候会通过WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先从servletContext中获取根上下文作为自己上下文的父上下文,它的实现类也是XmlWebApplicationContext,在建立之后会以和自己servlet-name便签有关的名称存储在servletContext中,这样每个servlet就拥有自己独立的bean及根上下文共享的bean

但是这样会导致重复加载配置文件,DispatcherServlet、ContextLoaderListener会分别加载一次,解决方法是把配置文件拆分成2个,一个Spring mvc的配置文件,一个Spring的配置文件,DispatcherServlet加载Spring mvc的配置文件,ContextLoaderListener加载Spring的配置文件 。
Spring mvc在使用上下文的时候会使用DispatcherServlet加载的applicationContext,也会使用的contextLoaderListener加载的applicationContext。

你可能感兴趣的:(Spring)