Spring.ResourceLoader



Spring.ResourceLoader_第1张图片
 
 

 


Spring.ResourceLoader_第2张图片
 

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.
	 * <p>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转换规则:(选择不同加载策略规则)



Spring.ResourceLoader_第3张图片
从DefaultResourceLoader.getResource(String location)可看出,未指定前缀时,通过getResourceByPath()获得Resource。不同ApplicationContext不同实现。

FileSystemXmlApplicationContext 覆盖getResourceByPath()方法,获得FileSystemResource

 

	/**
	 * Resolve resource paths as file system paths.
	 * <p>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策略模式应用

 
Spring.ResourceLoader_第4张图片
 

 

ResourceLoaderAware接口

 

void setResourceLoader(ResourceLoader resourceLoader);
 实现该接口的类部署到application context中时,context会识别为ResourceLoaderAware,application context 会调用 setResourceLoader方法,把自身作为参数传入该方法。(因为ApplicationContext 实现了ResourceLoader接口)

 

自动装配@Autowired  xml:autowire="byType"  代替接口实现

 

ApplicationContext中资源路径通配符

   ant风格路径表达式:

         *   匹配0或者任意数量的字符

         ? 匹配任何单字符

         **  匹配0或者更多的目录

URL路径说明
/app/*.x匹配(Matches)所有在app路径下的.x文件
/app/p?ttern匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern
/**/example匹配(Matches) /app/example, /app/foo/example, 和 /example
/app/**/dir/file.*匹配(Matches) /app/dir/file.jsp, /app/foo/dir/file.html,/app/foo/bar/dir/file.pdf, 和 /app/dir/file.java
/**/*.jsp匹配(Matches)任何的.jsp 文件

 

属性:
最长匹配原则(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

 

 

你可能感兴趣的:(ResourceLoader)