Spring加载resource时classpath*与cla
发布时间: 2012-10-27 10:42:26 作者: rapoo
Spring加载resource时classpath*:与classpath:的区别
Spring可以通过指定classpath*:与classpath:前缀加路径的方式从classpath加载文件,如bean的定义文件.classpath*:的出现是为了从多个jar文件中加载相同的文件.classpath:只能加载找到的第一个文件.
比如 resource1.jar中的package 'com.test.rs' 有一个 'jarAppcontext.xml' 文件,内容如下:
<bean name="ProcessorImplA" />
resource2.jar中的package 'com.test.rs' 也有一个 'jarAppcontext.xml' 文件,内容如下:
<bean id="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的?[java]?view plaincopy- 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/5560210,简介了在JAVA里遍历classpath中读取找到的所有符合名称的文件.
?
另外在加载resource的时候,其他前缀的意义如下表所示:注意classpath*只能用与指定配置文件的路径,不能用在用于getResource的参数.如appContext.getResource("classpath*:conf/bfactoryCtx.xml")会异常的.
?
前缀例子说明classpath:
[java]?view plaincopy- 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覆盖为如下:
[java]?view plaincopy- 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.
[java]?view plaincopy- 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.
[java]?view plaincopy- public?InputStream?getInputStream()?throws?IOException?{??
- ????InputStream?is?=?this.servletContext.getResourceAsStream(this.path);??
- ????if?(is?==?null)?{??
- ????????throw?new?FileNotFoundException("Could?not?open?"?+?getDescription());??
- ????}??
- ????return?is;??
- }??
?