spring报错parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]「建议收藏」

spring报错parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]「建议收藏」一、报错如下:org.springframework.beans.factory.BeanDefinitionStoreException:IOExceptionparsingXMLdocumentfromServletContextresource[/WEB-INF/applicationContext.xml];nestedexceptionisjava.io.F…

大家好,又见面了,我是你们的朋友全栈君。

一、 报错如下:


org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:176)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:211)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:182)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:138)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:580)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:460)
	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5118)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5634)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1571)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1561)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
	at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:140)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)
	... 21 more

  • 我的配置文件是在classes文件夹下的,在web.xml已经配置了xml的路径的,但是比较奇怪的是走了/WEB-INF/applicationContext.xml它的默认路径去找了。
  <!-- springMvc servlet -->
    <servlet>
        <servlet-name>manager</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>manager</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
     
    <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener>
     
  • 后来慢慢的发现这个情况出现在<listener>org.springframework.web.context.ContextLoaderListener的情况下,org.springframework.web.util.IntrospectorCleanupListener不会出现。

二、 查看下代码看看是怎么回事

  • 首先定位到ContextLoaderListener#contextInitialized方法
/**
	 
	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			this.contextLoader = this;
		}
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}
  • 发现最后调用initWebApplicationContext初始化应用上下文,下一步到ContextLoader#initWebApplicationContext方法
...................省略
//如果上下文不存在则创建
if (this.context == null) {
				this.context = createWebApplicationContext(servletContext);
			}
			if (this.context instanceof ConfigurableWebApplicationContext) {
				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
				if (!cwac.isActive()) {
					// The context has not yet been refreshed -> provide services such as
					// setting the parent context, setting the application context id, etc
					if (cwac.getParent() == null) {
						// The context instance was injected without an explicit parent ->
						// determine parent for root web application context, if any.
						ApplicationContext parent = loadParentContext(servletContext);
						cwac.setParent(parent);
					}
					//重点 最终到这里 配置和刷新上下文
					configureAndRefreshWebApplicationContext(cwac, servletContext);
				}
			}.
...................省略
  • 再到了configureAndRefreshWebApplicationContext方法
........................省略
	  //这个wac是XmlWebApplicationContext
        wac.setServletContext(sc);
        //这个CONFIG_LOCATION_PARAM的值就是contextConfigLocation
		String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
		//如果不等于null则设置配置文件路径 
		if (configLocationParam != null) {
			wac.setConfigLocation(configLocationParam);
		}

		// The wac environment's #initPropertySources will be called in any case when the context
		// is refreshed; do it eagerly here to ensure servlet property sources are in place for
		// use in any post-processing or initialization that occurs below prior to #refresh
		ConfigurableEnvironment env = wac.getEnvironment();
		if (env instanceof ConfigurableWebEnvironment) {
			((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
		}

		customizeContext(sc, wac);
		wac.refresh();
  • 好,上面是有配置contextConfigLocation的情况,那么如果没有配置contextConfigLocation的情况呢 ? 再往下看看这个XmlWebApplicationContext里面setConfigLocation方法。
  • 在这里插入图片描述
  • 可以看到XmlWebApplicationContext里面根本setConfigLocation方法,那么肯定会在它的父类。找找父类。
    在这里插入图片描述
  • 在AbstractRefreshableConfigApplicationContext找到了setConfigLocation方法,最终会把值放到configLocations数组里去。
public void setConfigLocation(String location) {
		setConfigLocations(StringUtils.tokenizeToStringArray(location, CONFIG_LOCATION_DELIMITERS));
	}

	/**
	 * Set the config locations for this application context.
	 * <p>If not set, the implementation may use a default as appropriate.
	 */
	public void setConfigLocations(String[] locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}
  • 再找到了获取configLocations的方法
//得到配置文件路径
	protected String[] getConfigLocations() {
		return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
	}

  • 已经很明显了如果没有配置contextConfigLocation则会调用XmlWebApplicationContext#getDefaultConfigLocations方法
/** Default config location for the root context */
	public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";

	/** Default prefix for building a config location for a namespace */
	public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";

	/** Default suffix for building a config location for a namespace */
	public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
 // 默认的配置文件路径
	@Override
	protected String[] getDefaultConfigLocations() {
		if (getNamespace() != null) {
			return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
		}
		else {
			return new String[] {DEFAULT_CONFIG_LOCATION};
		}
	}

三、解决方案

  • 到这里基本已经通了。
  <servlet>
        <servlet-name>manager</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>manager</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
  • 这个地方的contextConfigLocation是针对DispatcherServlet(contextConfigLocation属性在父类FrameworkServlet里)里初始化上下文用的,对ContextLoaderListener不起作用。
  • 看了下ContextLoaderListener的代码流程终于明白了,原来ContextLoaderListener要启动spring,需要得到配置文件的路径contextConfigLocation,如果不配置就会启用默认的路径。
  • 加上一个就好了 <context-param>
<?xml version="1.0" encoding="UTF-8"?>

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name>Archetype Created Web Application</display-name>
  
   <!-- springMvc servlet -->
    <servlet>
        <servlet-name>manager</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>manager</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
     
    <listener>
  
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener>
     
   <!-- 新加的 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
</web-app>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150721.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 电脑dnf,DNF卡顿如何解决_DNF卡顿如何解决 教你调整电脑参数畅玩游戏_52PKDNF「建议收藏」

    电脑dnf,DNF卡顿如何解决_DNF卡顿如何解决 教你调整电脑参数畅玩游戏_52PKDNF「建议收藏」DNF卡顿怎么解决?相信很多玩家电脑的配置并不差,但是就是玩DNF会卡。今天就在这里教大家一些优化的方法。让你轻松摆脱DNF卡顿带来的困扰。如果是硬件问题的可以换硬件,如果是软件设置问题的可以优化自己的设置。首先要说的由于系统版本和软件版本的问题,每一项设置带来的提升也会不同,需要各位玩家自己摸索,我也会讲一下自己在不同系统测试的感受。我的电脑信息:下面是方法汇总:一、硬件:1.显卡虽然之前一直有…

    2025年10月28日
    4
  • VB学习之路 ——基本语句

    VB学习之路 ——基本语句一:选择结构问题总结1.一个很简单的If(表达式)……..Then的问题,在VB的程序编写时候,如果在if….Then后面只有一条需要执行的语句,并且将执行的一条语句直接放在了Then的后面,则不需要后面加上EndIf,加上就报错。即使要执行的语句有多条如果非要放在Then后面不加EndIf就必须每条语句之间用冒号间隔。如果将执行的语句放在了Then的后面,即…

    2022年6月21日
    30
  • Dynamics Crm 2011 Or 2013 IFD 部署一段时间后,CA验证问题[通俗易懂]

    Dynamics Crm 2011 Or 2013 IFD 部署一段时间后,CA验证问题[通俗易懂]以下错误描述摘自博客:http://blog.csdn.net/qzw4549689/article/details/14451257IFD部署一段时间后,大概一年,突然出现从IFD登录页面登录后,再次弹出要求登录的框,多次输入用户名密码仍然无效,查看日志:><TraceRecordxmlns=”http://schemas.micros…

    2025年7月24日
    3
  • 大疆网上测评题库_【大疆在线测试有几套题啊?】-看准网

    大疆网上测评题库_【大疆在线测试有几套题啊?】-看准网写面经,攒人品。大疆服务运营培训生。1.大疆网上笔试题(比较独创,很有趣,也有歇跟大疆相关的题,要比较熟悉大疆),笔试过后,有岗位笔试作业。2.大疆服务运营培训生笔试作业题目。三道大题,开放性题目,专业和岗位相关,涉及报告类题目。规定期限内提交,审核,通过后进入面试环节。3.一面,微信视频面试。提前约定时间,到点准时打来,直奔主题。自我介绍,针对个人经历开始提问,最后会用英文简单问答一下看英语能力…

    2022年6月18日
    65
  • 政府大数据应用案例,政府大数据治理方法[通俗易懂]

    政府大数据应用案例,政府大数据治理方法[通俗易懂]​大数据不仅将改变生产方式、生活方式,社会组织方式尤其是政府治理也将因之发生深刻变革。以大数据提升政府治理能力是大势所趋。科技革命的加速推进特别是大数据时代的到来,迫切要求政府治理加快。大数据将成为加快政府治理能力现代化的最重要、最有力推手。在大数据思维下,基于大数据的科学决策、精细管理、精准服务将成为常态,将大大推动政府管理理念和社会治理模式进步,推进法治政府、创新政府、廉洁政府、智慧政府和服务型政府建设,逐步实现治理能力现代化。政府如何利用大数据提升治理水平?1.用数据说话治理理念的转变是提高政府

    2022年6月4日
    45
  • 操作系统用户态和内核态之间的切换过程是什么_用户进程从用户态切换到内核态

    操作系统用户态和内核态之间的切换过程是什么_用户进程从用户态切换到内核态操作系统用户态和内核态之间的切换过程1.用户态和内核态的概念区别究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上,先看一个例子:1)例子voidtestfork(){if(0==fork())…

    2022年9月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号