Linux环境下加载Spring的问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq354960984/article/details/70141000

问题描述:

最近在将项目部署到Linux环境下时,出现了加载spring.xml配置文件失败的问题,出错代码:

// Env.SPRING_PATH = /home/is/server/conf/spring.xml
springContext = new FileSystemXmlApplicationContext(Env.SPRING_PATH);

异常信息:

org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from file [/home/is/server/lib/home/is/server/conf/spring.xml]; nested exception is java.io.FileNotFoundException: home/is/server/conf/spring.xml (No such file or directory)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:252)
	at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127)
	at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:613)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:514)
	at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
	at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
	at com.is.Initializer.init(Initializer.java:36)
	at com.is.launcher.App.main(App.java:44)
Caused by: java.io.FileNotFoundException: home/is/server/conf/spring.xml (No such file or directory)
	at java.io.FileInputStream.open0(Native Method)
	at java.io.FileInputStream.open(FileInputStream.java:195)
	at java.io.FileInputStream.<init>(FileInputStream.java:138)
	at org.springframework.core.io.FileSystemResource.getInputStream(FileSystemResource.java:114)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)
	... 19 more

看异常,意思是说找不到 /home/is/server/lib/home/is/server/conf/spring.xml 这个文件,但实际上传入的文件路径是“/home/is/server/conf/spring.xml”,那为什么spring中该文件路径会发生变化呢?而且报错的路径是home/is/server/conf/spring.xml (注意:这里没有了“/”)。


说明:

异常消息中,前面的路径“/home/is/server/lib”实际上是当前运行程序的路径,如果切换到其它目录则会变成相应路径。


看FileSystemXmlApplicationContext类代码发现:

@Override
	protected Resource getResourceByPath(String path) {
		if (path != null && path.startsWith("/")) {
			path = path.substring(1);
		}
		return new FileSystemResource(path);
	}

该方法在获取资源时,会判断是否以“/”开头,如果是,则剥掉,导致Spring后续加载文件时使用的是不带“/”的文件路径,从而导致加载失败。


Why?

来看下getResourceByPath(String)方法的注释说明:

Resource org.springframework.context.support.FileSystemXmlApplicationContext.getResourceByPath(String path)

Resolve resource paths as file system paths. 

Note: Even if a given path starts with a slash, it will get interpreted as relative to the current VM working directory. This is consistent with the semantics in a Servlet container.


大意:

注:即使给定的路径以斜线开始,它将会被解释为相对当前VM工作目录。这与servlet容器中的语义相一致。

应该就是为了和JavaWeb开发时的环境、用法保持一致吧。


解决方法:

继承FileSystemXmlApplicationContext,重写getResourceByPath(String)方法,如下:

springContext = new FileSystemXmlApplicationContext(Env.SPRING_PATH) {
            @Override
            protected Resource getResourceByPath(String path) {
                if (path != null && path.startsWith("/")) {
                    // 忽略如下代码,使其在Linux环境能正常解析文件路径
                    // path = path.substring(1);
                }
                return new FileSystemResource(path);
            }
        };


OK,修改后可使用指定路径加载了!

展开阅读全文

没有更多推荐了,返回首页