DefaultResourceLoader:
ResourceLoader接口的默认实现,通过参数资源路径的前缀获得相应的Resource.
1、若以"classpath:"开头,则获得classPathResource
2、若location符合URL格式,如http:,ftp:,file:,jar等,则获得URLResource
3、1,2都不符合,表示无前缀或其他,则尝试getResourceByPath()方法获得Resource(默认:ClassPathContextResource)。子类通过getResourceByPath方法获得不同的Resource。如FileSystemXMLApplicationContext
DefaultResourceLoader代码:
public Resource getResource(String location) { Assert.notNull(location, "Location must not be null"); if (location.startsWith(CLASSPATH_URL_PREFIX)) { //1.若以"classpath:"开头,则表示使用classPathResource加载 return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader()); } else { try { //2.尝试是否符合URL格式,如http:,ftp:,file等 // 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. //3.不符合URL格式,则采用自定义形式加载。方法可子类覆盖,默认ClassPathContextResource return getResourceByPath(location); } } }
/** * Return a Resource handle for the resource at the given path. *The default implementation supports class path locations. This should * be appropriate for standalone implementations but can be overridden, * e.g. for implementations targeted at a Servlet container. * @param path the path to the resource * @return the corresponding Resource handle * @see ClassPathResource * @see org.springframework.context.support.FileSystemXmlApplicationContext#getResourceByPath * @see org.springframework.web.context.support.XmlWebApplicationContext#getResourceByPath */ protected Resource getResourceByPath(String path) { return new ClassPathContextResource(path, getClassLoader()); }
资源路径同Resource转换规则:(选择不同加载策略规则)
从DefaultResourceLoader.getResource(String location)可看出,未指定前缀时,通过getResourceByPath()获得Resource。不同ApplicationContext不同实现。
FileSystemXmlApplicationContext 覆盖getResourceByPath()方法,获得FileSystemResource
/** * 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. * @param path path to the resource * @return Resource handle * @see org.springframework.web.context.support.XmlWebApplicationContext#getResourceByPath */ @Override protected Resource getResourceByPath(String path) { if (path != null && path.startsWith("/")) { path = path.substring(1); } return new FileSystemResource(path); }
XmlWebApplicationContext:
/** * This implementation supports file paths beneath the root of the ServletContext. * @see ServletContextResource */ @Override protected Resource getResourceByPath(String path) { return new ServletContextResource(this.servletContext, path); }
ResourceLoader策略模式应用
ResourceLoaderAware接口
void setResourceLoader(ResourceLoader resourceLoader);实现该接口的类部署到application context中时,context会识别为ResourceLoaderAware,application context 会调用 setResourceLoader方法,把自身作为参数传入该方法。(因为ApplicationContext 实现了ResourceLoader接口)
自动装配@Autowired xml:autowire="byType" 代替接口实现
ApplicationContext中资源路径通配符
ant风格路径表达式:
* 匹配0或者任意数量的字符
? 匹配任何单字符
** 匹配0或者更多的目录
属性:
最长匹配原则(has more characters)
说明,URL请求/app/dir/file.jsp,现在存在两个路径匹配模式/**/*.jsp和/app/dir/*.jsp,那么会根据模式/app/dir/*.jsp来匹配
a) 资源路径前缀classpath: 同 classpath*: 区别
http://blog.csdn.net/zl3450341/article/details/9306983
1、classpath 只返回第一个匹配Resource,classpath* 返回所有匹配Resource
2、classpath*:直接跟通配符路径,则无法找到jar中的资源
public static void main(String[] args) { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); try { /** * 21 URL [file:/E:/xxx/target/classes/META-INF/MANIFEST.MF] URL [jar:file:/E:/xxx/lib/jboss-jmx.jar!/META-INF/MANIFEST.MF] URL [jar:file:/E:/xxx/lib/jboss-system.jar!/META-INF/MANIFEST.MF] */ Resource[] resources = resolver.getResources("classpath*:/META-INF/MANIFEST.MF"); /*only file [E:\xxxx\target\classes\META-INF\MANIFEST.MF] */ //Resource[] resources = resolver.getResources("classpath*:/META-INF*/MANIFEST*.MF"); System.out.println(resources.length); for(Resource res:resources){ System.out.println(res); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
b)
Spring 资源访问剖析和策略模式应用
深入Spring IOC源码之ResourceLoader