`

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

 
阅读更多

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.

[java] view plaincopy
 
  1. protected Resource[] findAllClassPathResources(String location) throws IOException {  
  2.     String path = location;  
  3.     if (path.startsWith("/")) {  
  4.         path = path.substring(1);  
  5.     }  
  6.     Enumeration resourceUrls = getClassLoader().getResources(path);  
  7.     Set<Resource> result = new LinkedHashSet<Resource>(16);  
  8.     while (resourceUrls.hasMoreElements()) {  
  9.         URL url = (URL) resourceUrls.nextElement();  
  10.         result.add(convertClassLoaderURL(url));  
  11.     }  
  12.     return result.toArray(new Resource[result.size()]);  
  13. }  

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

 

另外在加载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

[java] view plaincopy
 
  1. public Resource getResource(String location) {  
  2.         Assert.notNull(location, "Location must not be null");  
  3.         if (location.startsWith(CLASSPATH_URL_PREFIX)) {  
  4.             return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());  
  5.         }  
  6.         else {  
  7.             try {  
  8.                 // Try to parse the location as a URL...  
  9.                 URL url = new URL(location);  
  10.                 return new UrlResource(url);  
  11.             }  
  12.             catch (MalformedURLException ex) {  
  13.                 // No URL -> resolve as resource path.  
  14.                 return getResourceByPath(location);  
  15.             }  
  16.         }  
  17.     }  


getResourceByPath会被不同ApplicationContext 实现覆盖.

如 GenericWebApplicationContext覆盖为如下:

[java] view plaincopy
 
  1. protected Resource getResourceByPath(String path) {  
  2.         return new ServletContextResource(this.servletContext, path);  
  3.     }  
  4.   
  5. 如 FileSystemXmlApplicationContext覆盖为如下:  
  6.   
  7. protected Resource getResourceByPath(String path) {  
  8.         if (path != null && path.startsWith("/")) {  
  9.             path = path.substring(1);  
  10.         }  
  11.         return new FileSystemResource(path);  
  12.     }  

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

 

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

[java] view plaincopy
 
  1. public InputStream getInputStream() throws IOException {  
  2.     InputStream is;  
  3.     if (this.clazz != null) {  
  4.         is = this.clazz.getResourceAsStream(this.path);  
  5.     }  

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

 

    public InputStream getInputStream() throws IOException {
        return new FileInputStream(this.file);
    }

如ServletContextResource得到inputstream的方法是利用servletContext.getResourceAsStream.

[java] view plaincopy
 
  1. public InputStream getInputStream() throws IOException {  
  2.     InputStream is = this.servletContext.getResourceAsStream(this.path);  
  3.     if (is == null) {  
  4.         throw new FileNotFoundException("Could not open " + getDescription());  
  5.     }  
  6.     return is;  
  7. }  
分享到:
评论

相关推荐

    spring源代码

    Resource[] resources = resolver.getResources("classpath*:META-INF/INDEX.LIST"); Assert.assertTrue(resources.length &gt; 1); //将加载多个模式匹配的Resource resources = resolver.getResources(...

    webservice编写文档

    &lt;import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /&gt; &lt;import resource="classpath:META-INF/cxf/cxf-servlet.xml" /&gt; ...

    asm5.0.jar

    nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis- config.xml]; nested exception is org.apache.ibatis.builder....

    java高并发秒杀系统.rar

    mapper-locations: classpath*:/mapper/*Mapper.xml #配置Mybatis数据返回数据别名(默认别名是类名) type-aliases-package: com.csl.seckill.pojo logging: level: com.csl.seckill.mapper: debug 3.创建包 ...

    maven相关资料

    Spring中ClassPathXmlApplicationContext类的简单使用 Posted on 2011-06-22 17:08 xcp 阅读(14689) 评论(0) 编辑 收藏 所属分类: Spring 一、简单的用ApplicationContext做测试的话,获得Spring中定义的Bean实例...

    Spring AOP配置源码

    在类上标注@ContextConfiguration(locations="classpath:applicationContext.xml")意思是去classpath路径下加载applicationContext.xml @Resource(name="userService")意思是把userService注入进来 最终输出结果为:...

    springboot logback 自定义配置

    在application.propertiesa或yml中添加自定义logback的设置 logging.config=classpath:config/logback-spring.xml,把config文件夹复制到resource下即可,logback-spring.xml不需要修改,路径和日志大小格式等配置在...

    Spring.html

    ClassPathXmlApplicationContext:使用这个工厂创建对象,他会根据scope智能判断是否懒加载,如果是单例则创建容器时就会创建里面bean的实例,如果是多例在获取使用时才会创建bean实例 ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    classpath*: 前缀 4.7.2.3. 其他关于通配符的说明 4.7.3. FileSystemResource 提示 5. 校验,数据绑定,BeanWrapper,与属性编辑器 5.1. 简介 5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 ...

    Struts2+Spring3+MyBatis3完整实例

    网上的东西好大多都不能直接用,自己结合网上资料做了一个Struts2+Spring3+MyBatis3的测试工程,JUnit测试用例和WEB服务。...- Find registry server-registry.xml at classpath resource - Server startup in 5329 ms

    spring3.2+strut2+hibernate4

    &lt;value&gt;classpath*:jdbc.properties &lt;!-- 数据源配置,主要用于开发测试环境 --&gt; &lt;!-- &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt; --&gt; ${...

    springmybatis

    mybatis实战教程mybatis in action之五与spring3集成附源码 mybatis实战教程mybatis in action之六与Spring MVC 的集成 mybatis实战教程mybatis in action之七实现mybatis分页源码下载 mybatis实战教程mybatis in ...

    Spring中文帮助文档

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    Spring API

    6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入...

    基于datax实现data以rpc的方式传递json配置调用推数服务.zip

    url: jdbc:derby:${classpath:resource}/datax_metas_db;create=true username: root password: 123456 ribbon: # 同一实例最大重试次数,不包括首次调用 MaxAutoRetries: 1 # 重试其他实例的最大重试次数...

    Spring攻略(第二版 中文高清版).part1

    3.10 Spring中的AspectJ加载时织入aspect 140 3.10.1 问题 140 3.10.2 解决方案 141 3.10.3 工作原理 141 3.11 在Spring中配置AspectJ aspect 146 3.11.1 问题 146 3.11.2 解决方案 146 3.11.3 工作...

    spring-boot-reference.pdf

    Resource Conditions 46.3.5. Web Application Conditions 46.3.6. SpEL Expression Conditions 46.4. Testing your Auto-configuration 46.4.1. Simulating a Web Context 46.4.2. Overriding the Classpath 46.5....

    Spring攻略(第二版 中文高清版).part2

    3.10 Spring中的AspectJ加载时织入aspect 140 3.10.1 问题 140 3.10.2 解决方案 141 3.10.3 工作原理 141 3.11 在Spring中配置AspectJ aspect 146 3.11.1 问题 146 3.11.2 解决方案 146 3.11.3 工作...

    SpringMVC-SSH全注解

    &lt;value&gt;classpath:jdbc.properties &lt;!-- 配置數據源 --&gt; destroy-method="close"&gt; ${jdbc.driver}" /&gt; ${jdbc.url}" /&gt; ${jdbc.username}" /&gt; ${jdbc.password}" /&gt; &lt;!-- 连接池启动时的初始...

    SpringBoot集成Beetl的简单测试

    beetlGroupUtilConfiguration.setConfigFileResource(patternResolver.getResource("classpath:beetl.properties")); return beetlGroupUtilConfiguration; } @Bean(name = "beetlViewResolver") public ...

Global site tag (gtag.js) - Google Analytics