文档章节

Spring classpath:与classpath*:的区别

有理想的鸭子
 有理想的鸭子
发布于 2015/07/31 17:53
字数 791
阅读 45
收藏 2

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*:的使用是为了多个component(最终发布成不同的jar包)并行开发,各自的bean定义文件按照一定的规则:package+filename,而使用这些component的调用者可以把这些文件都加载进来.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()]);  
    }
 另外在加载resource的时候,其他前缀的意义如下表所示:注意 classpath*:只能用与指定配置文件的路径,不能用在用于 getResource的参数.如 appContext.getResource("classpath*:conf/bfactoryCtx.xml")会异常的.

 

 

前缀 例子 说明

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);
    }
 如ServletContextResource得到inputstream的方法是利用servletContext.getResourceAsStream.

 

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

© 著作权归作者所有

共有 人打赏支持
有理想的鸭子
粉丝 3
博文 47
码字总数 20092
作品 0
武汉
高级程序员
私信 提问
4、classpath: 与classpath*的区别

引用一篇很不错的文章:http://blog.csdn.net/wxwzy738/article/details/16983935 首先 classpath是指 WEB-INF文件夹下的classes目录 classpath 和 classpath* 区别: classpath:只会到你指定...

永远的Chester
2018/12/05
0
0
web.xml中classpath:和classpath*:

web.xml中classpath:和classpath*: 有什么区别? classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. 存放位置: 1:src下面...

leesama
2014/02/11
0
0
4、Spring配置中的"classpath:"与"classpath*:"的区别

一、概念解释及使用场景: classpath是指WEB-INF文件夹下的classes目录。 通常我们一般使用这种写法实在web.xml中,比如spring加载bean的上下文时,如下: 经过如上的写法,可能会认为这个就...

丑陋的皮囊
2018/07/14
0
0
Spring hibernate配置中mappingLocations、mappingDirecto

mappingLocations、mappingDirectoryLocations与mappingJarLocations 区别 由于spring对hibernate配置文件hibernate.cfg.xml的集成相当好, 所以,在项目中我一直使用spring的org.springfra...

lzw_me
2014/07/24
0
0
Spring4 MVC HelloWord实例

Spring4 MVC HelloWord实例 使用springWind /SpringWind/src/main/webapp/WEB-INF/web.xml 如果你不想用 SpringMVC 的使用原则,可以重新配置 SpringMVC DispatcherServlet 在 web.xml 文件中......

颖伙虫
2018/09/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

生产者消费者问题(PV操作)

一、明确定义 要理解生产消费者问题,首先应弄清PV操作的含义:PV操作是由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下: P(S):①将信号量S的值减...

shzwork
22分钟前
0
0
重新认识网络通信协议

OSI网络分层 应用层 http, smtp,pop3这些都属于应用层协议 为用户的应用程序提供服务 表示层 确保一个系统的应用层发送的信息被另一个系统的应用层接收到 会话层 通过传输层建立数据传输的通...

最胖的瘦子
33分钟前
1
0
【转】分布式数据流的轻量级异步快照

本篇翻译自论文:Lightweight Asynchronous Snapshots for Distributed Dataflows,Flink的容错快照模型即来源于该论文。原文地址:https://arxiv.org/pdf/1506.08603.pdf 分布式数据流的轻量...

yiduwangkai
35分钟前
0
0
java使用反射机制设置私有成员变量的值

写一个方法:public void setProperty(Objectobj, String propertyName, Object value){}, 此方法可将obj对象中名为propertyName的属性的值设置为value。(这里不知道obj对象的propertyNam...

群星纪元
41分钟前
0
0
用 Tapestry 的方式在页面模板中加入注释

<span jwcid="$remove$">这里是注释</span>

LeoXu
42分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部