Spring加载resource时classpath*:与classpath:的区别

Spring加载resource时classpath*:与classpath:的区别Spring 可以通过指定 classpath 与 classpath 前缀加路径的方式从 classpath 加载文件 如 bean 的定义文件 classpath 的出现是为了从多个 jar 文件中加载相同的文件 classpath 只能加载找到的第一个文件 比如 resource1 jar 中的 package com test rs 有一个 jarAppcontex xml 文件 内容如下

大家好,又见面了,我是你们的朋友全栈君。
如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Spring可以通过指定classpath*:与classpath:前缀加路径的方式从classpath加载文件,如bean的定义文件.classpath*:的出现是为了从多个jar文件中加载相同的文件.classpath:只能加载找到的第一个文件.

比如 resource1.jar中的package ‘com.test.rs’ 有一个 ‘jarAppcontext.xml’ 文件,内容如下:

<bean name=”ProcessorImplA” class=”com.test.spring.di.ProcessorImplA” />

resource2.jar中的package ‘com.test.rs’ 也有一个 ‘jarAppcontext.xml’ 文件,内容如下:

<bean id=”ProcessorImplB” class=”com.test.spring.di.ProcessorImplB” />

通过使用下面的代码则可以将两个jar包中的文件都加载进来

ApplicationContext ctx = new ClassPathXmlApplicationContext( “classpath*:com/test/rs/jarAppcontext.xml”);

而如果写成下面的代码,就只能找到其中的一个xml文件(顺序取决于jar包的加载顺序)

ApplicationContext ctx = new ClassPathXmlApplicationContext( “classpath:com/test/rs/jarAppcontext.xml”);

classpath*:的加载使用了classloader的 getResources() 方法,如果是在不同的J2EE服务器上运行,由于应用服务器提供自己的classloader实现,它们在处理jar文件时的行为也许会有所不同。 要测试classpath*: 是否有效,可以用classloader从classpath中的jar文件里加载文件来进行测试:getClass().getClassLoader().getResources("<someFileInsideTheJar>")。(上面的例子是在sun的jre中运行的状态)

 从Spring的源码,在PathMatchingResourcePatternResolver类中,我们可以更清楚的了解其对的处理:如果是以classpath*开头,它会遍历classpath.

 protected Resource[] findAllClassPathResources(String location) throws IOException { String path = location; if (path.startsWith("/")) { path = path.substring(1); } Enumeration resourceUrls = getClassLoader().getResources(path); Set<Resource> result = new LinkedHashSet<Resource>(16); while (resourceUrls.hasMoreElements()) { URL url = (URL) resourceUrls.nextElement(); result.add(convertClassLoaderURL(url)); } return result.toArray(new Resource[result.size()]); }

http://blog.csdn.net/kkdelta/article/details/,简介了在JAVA里遍历classpath中读取找到的所有符合名称的文件.

前缀 例子 说明

classpath:

classpath:com/myapp/config.xml

从classpath中加载。

file:

file:/data/config.xml

作为 URL 从文件系统中加载。

http:

http://myserver/logo.png

作为 URL 加载。

(none)

/data/config.xml

根据 ApplicationContext 进行判断。

从Spring的源码可以看出原因:如果是classpath:开头,从classpath加载,否则尝试URL,如果失败,调用 getResourceByPath

public Resource getResource(String location) { Assert.notNull(location, "Location must not be null"); if (location.startsWith(CLASSPATH_URL_PREFIX)) { return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader()); } else { try { // Try to parse the location as a URL... URL url = new URL(location); return new UrlResource(url); } catch (MalformedURLException ex) { // No URL -> resolve as resource path. return getResourceByPath(location); } } }

getResourceByPath会被不同 ApplicationContext 实现覆盖.

如 GenericWebApplicationContext覆盖为如下:

protected Resource getResourceByPath(String path) { return new ServletContextResource(this.servletContext, path); } 如 FileSystemXmlApplicationContext覆盖为如下: protected Resource getResourceByPath(String path) { if (path != null && path.startsWith("/")) { path = path.substring(1); } return new FileSystemResource(path); }

最终从文件加载的时候仍然是JAVA中常见的读取文件的方法:

如ClassPathResource得到inputstream的方法是利用class loader.

 public InputStream getInputStream() throws IOException { InputStream is; if (this.clazz != null) { is = this.clazz.getResourceAsStream(this.path); }

如FileSystemResource得到inputstream的方法是利用FileInputStream.

    public InputStream getInputStream() throws IOException {

        return new FileInputStream(this.file);
    }

 public InputStream getInputStream() throws IOException { InputStream is = this.servletContext.getResourceAsStream(this.path); if (is == null) { throw new FileNotFoundException("Could not open " + getDescription()); } return is; }

注意:
用classpath*:需要遍历所有的classpath,所以加载效率会比较差一些,如果只使用classpath:,需要规划好资源文件的路径,尽量避免重名,导致资源文件加载不到的问题。

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

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

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


相关推荐

  • matlab 画折线图

    matlab 画折线图代码:效果图:x=1:1:5就是x轴上的数据,从1开始到5结束(即应该有五个数据),每个数据的间隔是1.把开始的1改成2,结束的5改成6,整个折线图就会向右平移一个单位。plot(x,a,’-*b’,x,b,’-or’)是设置折线图中相应点和线的特征的,函数说明如下:对于‘’内的线条形状,总结了如下图:线型:线条宽度:指定线条的宽度,取值为整数(…

    2022年4月29日
    63
  • Nginx实战之反向代理WebSocket的配置实例

    Nginx实战之反向代理WebSocket的配置实例

    2021年10月14日
    53
  • stm32cubemx软件库_STM32cube

    stm32cubemx软件库_STM32cube前言:本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用在我们的HAL库中,对硬件SPI函数做了很好的集成,使得之前SPI几百行代码,在HAL库中,只需要寥寥几行就可以完成那么这篇文章将带你去感受下它的优异之处,这些优异的函数,也正是HAL库的优点所在所用工具:1、芯片:STM32F103ZET62、STM32CubeMx软件3、IDE:…

    2022年8月31日
    4
  • PID控制算法总结

    PID控制算法总结当今的闭环自动控制技术都是基于反馈的概念以减少不确定性。反馈理论的要素包括三个部分:测量、比较和执行。测量关键的是被控变量的实际值,与期望值相比较,用这个偏差来纠正系统的响应,执行调节控制。在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。一、PID含义PID是英文单词比例(Proportion),积分(Integral),微分(Di…

    2022年5月12日
    125
  • grep 命令详解_grep命令详解

    grep 命令详解_grep命令详解一:grep命令的基本概念和用途grep命令是linux中一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。在一个或多个文件中搜素字符串模式,如果字符串模式包括空格,也必须被引用,模式后的所有字符串被看作文件名。搜索的结果被送到标准输出(stdout),不影响原文件内容。grep也可以用于shell脚本,因为grep通过返回一个状态值来说明搜索的结果,如果模式搜索成功,则返回0;如果搜索不成功,则返回1;如果搜索的文件不存在,则返回2;我们利用这些返回值就可以进行一些自动化的文

    2022年8月30日
    5
  • Python 自定义包的导入问题 和 打包成exe无法在别的电脑运行的问题

    Python 自定义包的导入问题 和 打包成exe无法在别的电脑运行的问题

    2021年11月23日
    47

发表回复

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

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